From 9be35f82c1abf2ecbab489bca9eca138ea648312 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 Jul 2019 01:33:01 +0300 Subject: tests: Move run-pass tests without naming conflicts to ui --- src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs | 304 -- .../run-pass-fulldeps/auxiliary/issue-13560-1.rs | 3 - .../run-pass-fulldeps/auxiliary/issue-13560-2.rs | 3 - .../run-pass-fulldeps/auxiliary/issue-13560-3.rs | 6 - .../run-pass-fulldeps/auxiliary/issue-16822.rs | 20 - .../run-pass-fulldeps/auxiliary/issue-18502.rs | 21 - .../run-pass-fulldeps/auxiliary/issue-24106.rs | 13 - .../auxiliary/issue-40001-plugin.rs | 57 - .../auxiliary/linkage-visibility.rs | 37 - .../run-pass-fulldeps/auxiliary/lint-for-crate.rs | 74 - .../auxiliary/llvm-pass-plugin.rs | 20 - .../auxiliary/lto-syntax-extension-lib.rs | 5 - .../auxiliary/lto-syntax-extension-plugin.rs | 13 - .../auxiliary/macro-crate-test.rs | 35 - .../auxiliary/outlive-expansion-phase.rs | 26 - .../run-pass-fulldeps/auxiliary/plugin-args.rs | 44 - .../run-pass-fulldeps/auxiliary/roman-numerals.rs | 70 - .../auxiliary/syntax-extension-with-dll-deps-1.rs | 7 - src/test/run-pass-fulldeps/compiler-calls.rs | 31 - src/test/run-pass-fulldeps/create-dir-all-bare.rs | 11 - .../derive-no-std-not-supported.rs | 22 - .../deriving-encodable-decodable-box.rs | 24 - .../deriving-encodable-decodable-cell-refcell.rs | 37 - src/test/run-pass-fulldeps/deriving-global.rs | 35 - src/test/run-pass-fulldeps/deriving-hygiene.rs | 19 - .../run-pass-fulldeps/dropck_tarena_sound_drop.rs | 43 - .../empty-struct-braces-derive.rs | 56 - src/test/run-pass-fulldeps/extern-mod-syntax.rs | 11 - src/test/run-pass-fulldeps/issue-11881.rs | 52 - src/test/run-pass-fulldeps/issue-13560.rs | 12 - src/test/run-pass-fulldeps/issue-14021.rs | 25 - src/test/run-pass-fulldeps/issue-15149.rs | 56 - src/test/run-pass-fulldeps/issue-15778-pass.rs | 15 - src/test/run-pass-fulldeps/issue-15924.rs | 27 - src/test/run-pass-fulldeps/issue-16822.rs | 22 - src/test/run-pass-fulldeps/issue-18502.rs | 8 - src/test/run-pass-fulldeps/issue-24106.rs | 8 - src/test/run-pass-fulldeps/issue-24972.rs | 29 - src/test/run-pass-fulldeps/issue-2804.rs | 70 - src/test/run-pass-fulldeps/issue-40001.rs | 9 - src/test/run-pass-fulldeps/issue-4016.rs | 20 - src/test/run-pass-fulldeps/issue-4036.rs | 17 - src/test/run-pass-fulldeps/linkage-visibility.rs | 13 - src/test/run-pass-fulldeps/llvm-pass-plugin.rs | 8 - src/test/run-pass-fulldeps/lto-syntax-extension.rs | 15 - .../macro-crate-multi-decorator.rs | 49 - .../mod_dir_path_canonicalized.rs | 29 - .../mod_dir_simple/compiletest-ignore-dir | 0 src/test/run-pass-fulldeps/mod_dir_simple/test.rs | 3 - src/test/run-pass-fulldeps/myriad-closures.rs | 39 - src/test/run-pass-fulldeps/newtype_index.rs | 22 - .../run-pass-fulldeps/outlive-expansion-phase.rs | 8 - src/test/run-pass-fulldeps/plugin-args-1.rs | 10 - src/test/run-pass-fulldeps/plugin-args-2.rs | 10 - src/test/run-pass-fulldeps/plugin-args-3.rs | 10 - .../run-pass-fulldeps/pprust-expr-roundtrip.rs | 230 -- src/test/run-pass-fulldeps/regions-mock-tcx.rs | 134 - src/test/run-pass-fulldeps/rename-directory.rs | 30 - src/test/run-pass-fulldeps/roman-numerals-macro.rs | 15 - .../run-pass-fulldeps/rustc_encodable_hygiene.rs | 24 - src/test/run-pass-fulldeps/stdio-from.rs | 69 - src/test/run-pass-fulldeps/switch-stdout.rs | 52 - src/test/run-pass-fulldeps/undef_mask.rs | 27 - src/test/run-pass/.gitattributes | 1 - src/test/run-pass/abi-sysv64-arg-passing.rs | 367 -- src/test/run-pass/abi-sysv64-register-usage.rs | 96 - .../abi/issues/issue-62350-sysv-neg-reg-counts.rs | 46 - src/test/run-pass/abort-on-c-abi.rs | 38 - src/test/run-pass/alias-uninit-value.rs | 20 - src/test/run-pass/align-with-extern-c-fn.rs | 17 - src/test/run-pass/alignment-gep-tup-like-1.rs | 39 - src/test/run-pass/alloca-from-derived-tydesc.rs | 15 - src/test/run-pass/allocator-alloc-one.rs | 18 - .../allocator/auxiliary/custom-as-global.rs | 16 - src/test/run-pass/allocator/auxiliary/custom.rs | 21 - src/test/run-pass/allocator/auxiliary/helper.rs | 9 - src/test/run-pass/allocator/custom-in-block.rs | 22 - src/test/run-pass/allocator/custom-in-submodule.rs | 26 - src/test/run-pass/allocator/custom.rs | 58 - src/test/run-pass/allocator/xcrate-use.rs | 35 - src/test/run-pass/allocator/xcrate-use2.rs | 47 - src/test/run-pass/anon-extern-mod.rs | 18 - src/test/run-pass/argument-passing.rs | 25 - src/test/run-pass/array-slice-vec/arr_cycle.rs | 31 - .../array-slice-vec/array_const_index-1.rs | 12 - .../array-slice-vec/box-of-array-of-drop-1.rs | 47 - .../array-slice-vec/box-of-array-of-drop-2.rs | 47 - .../run-pass/array-slice-vec/cast-in-array-size.rs | 14 - .../array-slice-vec/check-static-mut-slices.rs | 15 - .../run-pass/array-slice-vec/check-static-slice.rs | 36 - .../array-slice-vec/copy-out-of-array-1.rs | 19 - .../array-slice-vec/destructure-array-1.rs | 27 - .../run-pass/array-slice-vec/empty-mutable-vec.rs | 8 - src/test/run-pass/array-slice-vec/estr-slice.rs | 50 - src/test/run-pass/array-slice-vec/evec-slice.rs | 47 - .../run-pass/array-slice-vec/fixed_length_copy.rs | 9 - .../run-pass/array-slice-vec/huge-largest-array.rs | 14 - .../run-pass/array-slice-vec/ivec-pass-by-value.rs | 4 - ...mutability-inherits-through-fixed-length-vec.rs | 19 - .../run-pass/array-slice-vec/mutable-alias-vec.rs | 15 - src/test/run-pass/array-slice-vec/nested-vec-1.rs | 8 - src/test/run-pass/array-slice-vec/nested-vec-2.rs | 15 - src/test/run-pass/array-slice-vec/nested-vec-3.rs | 54 - .../array-slice-vec/new-style-fixed-length-vec.rs | 7 - .../array-slice-vec/rcvr-borrowed-to-slice.rs | 33 - .../array-slice-vec/repeated-vector-syntax.rs | 13 - .../run-pass/array-slice-vec/show-boxed-slice.rs | 8 - src/test/run-pass/array-slice-vec/slice-2.rs | 62 - .../array-slice-vec/slice-of-zero-size-elements.rs | 53 - src/test/run-pass/array-slice-vec/slice-panic-1.rs | 26 - src/test/run-pass/array-slice-vec/slice-panic-2.rs | 30 - src/test/run-pass/array-slice-vec/slice.rs | 81 - .../array-slice-vec/slice_binary_search.rs | 21 - .../array-slice-vec/variance-vec-covariant.rs | 20 - src/test/run-pass/array-slice-vec/vec-concat.rs | 14 - src/test/run-pass/array-slice-vec/vec-dst.rs | 26 - .../run-pass/array-slice-vec/vec-fixed-length.rs | 24 - src/test/run-pass/array-slice-vec/vec-growth.rs | 16 - src/test/run-pass/array-slice-vec/vec-late-init.rs | 9 - .../run-pass/array-slice-vec/vec-macro-no-std.rs | 27 - .../run-pass/array-slice-vec/vec-macro-repeat.rs | 15 - .../array-slice-vec/vec-macro-rvalue-scope.rs | 11 - .../array-slice-vec/vec-macro-with-brackets.rs | 16 - .../vec-macro-with-trailing-comma.rs | 8 - .../array-slice-vec/vec-matching-autoslice.rs | 23 - .../run-pass/array-slice-vec/vec-matching-fixed.rs | 32 - .../run-pass/array-slice-vec/vec-matching-fold.rs | 48 - .../vec-matching-legal-tail-element-borrow.rs | 16 - src/test/run-pass/array-slice-vec/vec-matching.rs | 159 - src/test/run-pass/array-slice-vec/vec-push.rs | 3 - .../array-slice-vec/vec-repeat-with-cast.rs | 5 - .../run-pass/array-slice-vec/vec-slice-drop.rs | 31 - src/test/run-pass/array-slice-vec/vec-slice.rs | 9 - .../run-pass/array-slice-vec/vec-tail-matching.rs | 36 - src/test/run-pass/array-slice-vec/vec-to_str.rs | 12 - src/test/run-pass/array-slice-vec/vec.rs | 15 - src/test/run-pass/array-slice-vec/vec_cycle.rs | 39 - .../run-pass/array-slice-vec/vec_cycle_wrapped.rs | 50 - .../run-pass/array-slice-vec/vector-no-ann-2.rs | 7 - src/test/run-pass/artificial-block.rs | 5 - src/test/run-pass/as-precedence.rs | 9 - src/test/run-pass/asm-concat-src.rs | 9 - src/test/run-pass/asm-in-moved.rs | 31 - src/test/run-pass/asm-in-out-operand.rs | 56 - src/test/run-pass/asm-indirect-memory.rs | 43 - src/test/run-pass/asm-out-assign.rs | 25 - src/test/run-pass/assert-eq-trailing-comma.rs | 5 - src/test/run-pass/assert-escape.rs | 5 - src/test/run-pass/assert-ne-trailing-comma.rs | 5 - src/test/run-pass/assign-assign.rs | 30 - src/test/run-pass/assoc-oddities-3.rs | 13 - .../associated-const-const-eval.rs | 20 - .../associated-const-cross-crate-const-eval.rs | 28 - .../associated-const-cross-crate-defaults.rs | 22 - .../associated-const-cross-crate.rs | 17 - .../associated-const-in-global-const.rs | 13 - .../associated-const-inherent-impl.rs | 11 - .../associated-const-marks-live-code.rs | 15 - .../associated-const-match-patterns.rs | 68 - .../associated-const-outer-ty-refs.rs | 10 - .../associated-const-overwrite-default.rs | 13 - .../associated-const-public-impl.rs | 16 - .../associated-const-range-match-patterns.rs | 40 - .../associated-const-resolution-order.rs | 25 - .../associated-const-self-type.rs | 13 - .../associated-const-type-parameters.rs | 44 - .../associated-const-ufcs-infer-trait.rs | 13 - .../associated-const-use-default.rs | 11 - .../associated-const-use-impl-of-same-trait.rs | 25 - .../run-pass/associated-consts/associated-const.rs | 13 - .../auxiliary/associated-const-cc-lib.rs | 34 - .../associated-consts/auxiliary/empty-struct.rs | 9 - src/test/run-pass/associated-item-long-paths.rs | 47 - .../associated-types/associated-types-basic.rs | 14 - .../associated-types-binding-in-trait.rs | 36 - .../associated-types-binding-in-where-clause.rs | 38 - .../associated-types/associated-types-bound.rs | 43 - .../associated-types/associated-types-cc.rs | 18 - .../associated-types-conditional-dispatch.rs | 66 - .../associated-types-constant-type.rs | 31 - .../associated-types-doubleendediterator-object.rs | 20 - ...sociated-types-duplicate-binding-in-env-hrtb.rs | 17 - .../associated-types-duplicate-binding-in-env.rs | 21 - .../associated-types-enum-field-named.rs | 35 - .../associated-types-enum-field-numbered.rs | 35 - .../associated-types/associated-types-eq-obj.rs | 25 - .../associated-types-from-supertrait.rs | 8 - .../associated-types-impl-redirect.rs | 51 - .../associated-types-in-bound-type-arg.rs | 17 - .../associated-types-in-default-method.rs | 27 - .../associated-types/associated-types-in-fn.rs | 28 - .../associated-types-in-impl-generics.rs | 36 - .../associated-types-in-inherent-method.rs | 30 - .../associated-types-issue-20220.rs | 28 - .../associated-types-issue-20371.rs | 9 - .../associated-types-issue-21212.rs | 22 - .../associated-types-iterator-binding.rs | 19 - .../associated-types/associated-types-method.rs | 27 - .../associated-types-nested-projections.rs | 44 - ...associated-types-normalize-in-bounds-binding.rs | 38 - .../associated-types-normalize-in-bounds-ufcs.rs | 35 - .../associated-types-normalize-in-bounds.rs | 35 - .../associated-types-normalize-unifield-struct.rs | 24 - ...s-project-from-type-param-via-bound-in-where.rs | 98 - ...ciated-types-projection-bound-in-supertraits.rs | 23 - ...ted-types-projection-from-known-type-in-impl.rs | 38 - .../associated-types-projection-in-object-type.rs | 40 - .../associated-types-projection-in-supertrait.rs | 45 - .../associated-types-projection-in-where-clause.rs | 31 - ...sociated-types-projection-to-unrelated-trait.rs | 35 - ...alified-path-with-trait-with-type-parameters.rs | 9 - .../associated-types-ref-from-struct.rs | 55 - .../associated-types-ref-in-struct-literal.rs | 23 - .../associated-types-region-erasure-issue-20582.rs | 21 - .../associated-types-resolve-lifetime.rs | 15 - .../associated-types/associated-types-return.rs | 46 - .../associated-types/associated-types-simple.rs | 24 - .../associated-types/associated-types-stream.rs | 39 - .../associated-types-struct-field-named.rs | 35 - .../associated-types-struct-field-numbered.rs | 32 - .../associated-types-sugar-path.rs | 41 - ...associated-types-where-clause-impl-ambiguity.rs | 46 - .../auxiliary/associated-types-cc-lib.rs | 16 - src/test/run-pass/atomic-access-bool.rs | 24 - src/test/run-pass/atomic-alignment.rs | 38 - src/test/run-pass/atomic-compare_exchange.rs | 31 - src/test/run-pass/atomic-print.rs | 46 - src/test/run-pass/attr-main-2.rs | 11 - src/test/run-pass/attr-main.rs | 8 - src/test/run-pass/attr-shebang.rs | 6 - src/test/run-pass/attr-start.rs | 9 - src/test/run-pass/attr.rs | 8 - .../augmented-assignments-feature-gate-cross.rs | 11 - .../run-pass/augmented-assignments-feature-gate.rs | 15 - src/test/run-pass/auto-instantiate.rs | 13 - src/test/run-pass/auto-is-contextual.rs | 18 - src/test/run-pass/autobind.rs | 12 - .../autoref-autoderef/auto-ref-bounded-ty-param.rs | 29 - .../autoref-autoderef/auto-ref-sliceable.rs | 19 - src/test/run-pass/autoref-autoderef/auto-ref.rs | 19 - .../autoderef-and-borrow-method-receiver.rs | 18 - .../autoref-autoderef/autoderef-method-on-trait.rs | 16 - .../autoref-autoderef/autoderef-method-priority.rs | 20 - .../autoderef-method-twice-but-not-thrice.rs | 16 - .../autoref-autoderef/autoderef-method-twice.rs | 16 - .../run-pass/autoref-autoderef/autoderef-method.rs | 16 - .../autoref-autoderef/autoderef-privacy.rs | 51 - .../autoref-intermediate-types-issue-3585.rs | 23 - .../auxiliary/anon-extern-mod-cross-crate-1.rs | 9 - .../run-pass/auxiliary/augmented_assignments.rs | 8 - .../blind-item-mixed-crate-use-item-foo.rs | 3 - .../blind-item-mixed-crate-use-item-foo2.rs | 3 - .../check_static_recursion_foreign_helper.rs | 11 - src/test/run-pass/auxiliary/cond_plugin.rs | 38 - .../auxiliary/crate-method-reexport-grrrrrrr2.rs | 31 - src/test/run-pass/auxiliary/debuginfo-lto-aux.rs | 29 - .../run-pass/auxiliary/edition-kw-macro-2015.rs | 26 - .../run-pass/auxiliary/edition-kw-macro-2018.rs | 26 - src/test/run-pass/auxiliary/foreign_lib.rs | 38 - src/test/run-pass/auxiliary/hello_macro.rs | 21 - src/test/run-pass/auxiliary/impl_privacy_xc_1.rs | 9 - src/test/run-pass/auxiliary/impl_privacy_xc_2.rs | 13 - src/test/run-pass/auxiliary/inline_dtor.rs | 8 - src/test/run-pass/auxiliary/inner_static.rs | 51 - src/test/run-pass/auxiliary/kinds_in_metadata.rs | 8 - .../auxiliary/link-cfg-works-transitive-dylib.rs | 4 - .../auxiliary/link-cfg-works-transitive-rlib.rs | 7 - src/test/run-pass/auxiliary/linkage1.rs | 4 - src/test/run-pass/auxiliary/llvm_pr32379.rs | 5 - src/test/run-pass/auxiliary/msvc-data-only-lib.rs | 5 - src/test/run-pass/auxiliary/nested_item.rs | 30 - src/test/run-pass/auxiliary/proc_macro_def.rs | 35 - .../auxiliary/reachable-unnameable-items.rs | 106 - .../auxiliary/reexport-should-still-link.rs | 5 - src/test/run-pass/auxiliary/rmeta-rmeta.rs | 9 - src/test/run-pass/auxiliary/svh-a-base.rs | 25 - src/test/run-pass/auxiliary/svh-b.rs | 13 - .../auxiliary/trait_superkinds_in_metadata.rs | 8 - .../run-pass/auxiliary/typeid-intrinsic-aux1.rs | 29 - .../run-pass/auxiliary/typeid-intrinsic-aux2.rs | 29 - .../auxiliary/using-target-feature-unstable.rs | 5 - src/test/run-pass/backtrace-debuginfo-aux.rs | 14 - src/test/run-pass/backtrace-debuginfo.rs | 180 - src/test/run-pass/backtrace.rs | 125 - src/test/run-pass/bare-fn-implements-fn-mut.rs | 27 - src/test/run-pass/bare-static-string.rs | 6 - src/test/run-pass/bench/issue-32062.rs | 50 - src/test/run-pass/big-literals.rs | 17 - src/test/run-pass/binary-minus-without-space.rs | 8 - src/test/run-pass/bind-by-move.rs | 13 - .../binding/bind-field-short-with-modifiers.rs | 26 - .../run-pass/binding/borrowed-ptr-pattern-2.rs | 13 - .../run-pass/binding/borrowed-ptr-pattern-3.rs | 13 - .../binding/borrowed-ptr-pattern-infallible.rs | 8 - .../binding/borrowed-ptr-pattern-option.rs | 15 - src/test/run-pass/binding/borrowed-ptr-pattern.rs | 12 - .../run-pass/binding/empty-types-in-patterns.rs | 58 - .../binding/exhaustive-bool-match-sanity.rs | 22 - .../run-pass/binding/expr-match-generic-unique1.rs | 19 - .../run-pass/binding/expr-match-generic-unique2.rs | 17 - src/test/run-pass/binding/expr-match-generic.rs | 29 - src/test/run-pass/binding/expr-match-panic-all.rs | 14 - src/test/run-pass/binding/expr-match-panic.rs | 14 - src/test/run-pass/binding/expr-match-unique.rs | 10 - src/test/run-pass/binding/expr-match.rs | 45 - src/test/run-pass/binding/fat-arrow-match.rs | 17 - .../fn-arg-incomplete-pattern-drop-order.rs | 69 - .../run-pass/binding/fn-pattern-expected-type-2.rs | 8 - .../run-pass/binding/fn-pattern-expected-type.rs | 9 - .../binding/func-arg-incomplete-pattern.rs | 24 - src/test/run-pass/binding/func-arg-ref-pattern.rs | 28 - src/test/run-pass/binding/func-arg-wild-pattern.rs | 12 - src/test/run-pass/binding/if-let.rs | 60 - .../binding/inconsistent-lifetime-mismatch.rs | 15 - .../binding/inferred-suffix-in-pattern-range.rs | 24 - .../run-pass/binding/irrefutable-slice-patterns.rs | 15 - src/test/run-pass/binding/let-assignability.rs | 12 - src/test/run-pass/binding/let-destruct-ref.rs | 7 - src/test/run-pass/binding/let-var-hygiene.rs | 11 - src/test/run-pass/binding/match-arm-statics.rs | 164 - src/test/run-pass/binding/match-beginning-vert.rs | 19 - src/test/run-pass/binding/match-borrowed_str.rs | 48 - src/test/run-pass/binding/match-bot-2.rs | 6 - src/test/run-pass/binding/match-bot.rs | 7 - .../run-pass/binding/match-byte-array-patterns.rs | 45 - src/test/run-pass/binding/match-enum-struct-0.rs | 17 - src/test/run-pass/binding/match-enum-struct-1.rs | 19 - .../run-pass/binding/match-implicit-copy-unique.rs | 17 - src/test/run-pass/binding/match-in-macro.rs | 17 - src/test/run-pass/binding/match-join.rs | 20 - src/test/run-pass/binding/match-larger-const.rs | 12 - .../run-pass/binding/match-naked-record-expr.rs | 12 - src/test/run-pass/binding/match-naked-record.rs | 13 - src/test/run-pass/binding/match-path.rs | 14 - .../run-pass/binding/match-pattern-bindings.rs | 21 - src/test/run-pass/binding/match-pattern-lit.rs | 15 - .../binding/match-pattern-no-type-params.rs | 14 - src/test/run-pass/binding/match-pattern-simple.rs | 9 - src/test/run-pass/binding/match-phi.rs | 19 - src/test/run-pass/binding/match-pipe-binding.rs | 60 - src/test/run-pass/binding/match-range-infer.rs | 17 - src/test/run-pass/binding/match-range-static.rs | 13 - src/test/run-pass/binding/match-range.rs | 51 - src/test/run-pass/binding/match-reassign.rs | 21 - .../binding/match-ref-binding-in-guard-3256.rs | 13 - .../binding/match-ref-binding-mut-option.rs | 10 - src/test/run-pass/binding/match-ref-binding-mut.rs | 18 - src/test/run-pass/binding/match-ref-binding.rs | 12 - src/test/run-pass/binding/match-ref-unsized.rs | 11 - src/test/run-pass/binding/match-str.rs | 25 - src/test/run-pass/binding/match-struct-0.rs | 21 - src/test/run-pass/binding/match-tag.rs | 30 - src/test/run-pass/binding/match-unique-bind.rs | 12 - src/test/run-pass/binding/match-unsized.rs | 9 - .../binding/match-value-binding-in-guard-3291.rs | 19 - src/test/run-pass/binding/match-var-hygiene.rs | 11 - .../run-pass/binding/match-vec-alternatives.rs | 81 - src/test/run-pass/binding/match-vec-rvalue.rs | 15 - src/test/run-pass/binding/match-with-ret-arm.rs | 12 - src/test/run-pass/binding/multi-let.rs | 7 - src/test/run-pass/binding/mut-in-ident-patterns.rs | 76 - .../run-pass/binding/nested-exhaustive-match.rs | 14 - src/test/run-pass/binding/nested-matchs.rs | 16 - src/test/run-pass/binding/nested-pattern.rs | 16 - src/test/run-pass/binding/nil-pattern.rs | 4 - src/test/run-pass/binding/nullary-or-pattern.rs | 13 - .../binding/optional_comma_in_match_arm.rs | 40 - src/test/run-pass/binding/or-pattern.rs | 14 - src/test/run-pass/binding/order-drop-with-match.rs | 57 - src/test/run-pass/binding/pat-ranges.rs | 20 - src/test/run-pass/binding/pat-tuple-1.rs | 93 - src/test/run-pass/binding/pat-tuple-2.rs | 23 - src/test/run-pass/binding/pat-tuple-3.rs | 29 - src/test/run-pass/binding/pat-tuple-4.rs | 57 - src/test/run-pass/binding/pat-tuple-5.rs | 29 - src/test/run-pass/binding/pat-tuple-6.rs | 45 - src/test/run-pass/binding/pat-tuple-7.rs | 8 - .../binding/pattern-bound-var-in-for-each.rs | 20 - src/test/run-pass/binding/pattern-in-closure.rs | 14 - .../binding/range-inclusive-pattern-precedence.rs | 23 - src/test/run-pass/binding/simple-generic-match.rs | 8 - src/test/run-pass/binding/use-uninit-match.rs | 17 - src/test/run-pass/binding/use-uninit-match2.rs | 18 - .../run-pass/binding/zero_sized_subslice_match.rs | 12 - src/test/run-pass/binops-issue-22743.rs | 24 - src/test/run-pass/binops.rs | 89 - src/test/run-pass/bitwise.rs | 34 - src/test/run-pass/blind-item-local-shadow.rs | 13 - .../run-pass/blind-item-mixed-crate-use-item.rs | 26 - src/test/run-pass/blind-item-mixed-use-item.rs | 20 - src/test/run-pass/block-arg-call-as.rs | 12 - src/test/run-pass/block-arg.rs | 11 - src/test/run-pass/block-explicit-types.rs | 6 - src/test/run-pass/block-expr-precedence.rs | 61 - src/test/run-pass/block-fn-coerce.rs | 10 - src/test/run-pass/block-iter-1.rs | 15 - src/test/run-pass/block-iter-2.rs | 15 - src/test/run-pass/bool-not.rs | 6 - src/test/run-pass/bool.rs | 72 - src/test/run-pass/borrow-by-val-method-receiver.rs | 14 - .../borrowck/borrowck-assign-to-subfield.rs | 23 - .../borrowck/borrowck-assignment-to-static-mut.rs | 11 - .../run-pass/borrowck/borrowck-binding-mutbl.rs | 16 - .../borrowck/borrowck-borrow-from-expr-block.rs | 18 - .../borrowck-borrow-of-mut-base-ptr-safe.rs | 21 - .../run-pass/borrowck/borrowck-closures-two-imm.rs | 41 - .../borrowck/borrowck-fixed-length-vecs.rs | 7 - .../borrowck/borrowck-freeze-frozen-mut.rs | 28 - src/test/run-pass/borrowck/borrowck-lend-args.rs | 21 - .../borrowck-macro-interaction-issue-6304.rs | 38 - .../borrowck/borrowck-move-by-capture-ok.rs | 8 - .../borrowck-multiple-borrows-interior-boxes.rs | 20 - src/test/run-pass/borrowck/borrowck-mut-uniq.rs | 33 - .../borrowck/borrowck-mut-vec-as-imm-slice.rs | 16 - src/test/run-pass/borrowck/borrowck-pat-enum.rs | 39 - .../borrowck/borrowck-pat-reassign-no-binding.rs | 14 - .../run-pass/borrowck/borrowck-rvalues-mutable.rs | 34 - .../borrowck/borrowck-scope-of-deref-issue-4666.rs | 42 - .../borrowck/borrowck-static-item-in-fn.rs | 9 - .../run-pass/borrowck/borrowck-trait-lifetime.rs | 18 - .../run-pass/borrowck/borrowck-uniq-via-ref.rs | 49 - .../run-pass/borrowck/borrowck-univariant-enum.rs | 25 - .../borrowck-unsafe-static-mutable-borrows.rs | 20 - .../borrowck/borrowck-unused-mut-locals.rs | 46 - .../run-pass/borrowck/issue-62007-assign-box.rs | 27 - .../run-pass/borrowck/issue-62007-assign-field.rs | 26 - src/test/run-pass/borrowck/two-phase-baseline.rs | 9 - src/test/run-pass/borrowck/two-phase-bin-ops.rs | 35 - ...o-phase-control-flow-split-before-activation.rs | 15 - src/test/run-pass/box-new.rs | 6 - src/test/run-pass/bug-7183-generics.rs | 36 - src/test/run-pass/bug-7295.rs | 14 - src/test/run-pass/builtin-clone-unwind.rs | 61 - src/test/run-pass/builtin-clone.rs | 45 - .../builtin-superkinds-capabilities-transitive.rs | 25 - .../run-pass/builtin-superkinds-capabilities-xc.rs | 27 - .../run-pass/builtin-superkinds-capabilities.rs | 21 - .../run-pass/builtin-superkinds-in-metadata.rs | 23 - .../run-pass/builtin-superkinds-phantom-typaram.rs | 18 - src/test/run-pass/builtin-superkinds-simple.rs | 10 - src/test/run-pass/builtin-superkinds-typaram.rs | 11 - src/test/run-pass/byte-literals.rs | 67 - src/test/run-pass/c-stack-as-value.rs | 18 - src/test/run-pass/c-stack-returning-int64.rs | 34 - src/test/run-pass/cabi-int-widening.rs | 15 - src/test/run-pass/can-copy-pod.rs | 16 - .../cancel-clean-via-immediate-rvalue-ref.rs | 12 - src/test/run-pass/cast-does-fallback.rs | 12 - src/test/run-pass/cast-region-to-uint.rs | 6 - src/test/run-pass/cast-rfc0401-vtable-kinds.rs | 62 - src/test/run-pass/cast-rfc0401.rs | 173 - src/test/run-pass/cast-to-infer-ty.rs | 8 - src/test/run-pass/cast.rs | 21 - src/test/run-pass/catch-unwind-bang.rs | 10 - src/test/run-pass/cell-does-not-clone.rs | 26 - .../run-pass/cfg/auxiliary/cfg_inner_static.rs | 7 - .../auxiliary/crate-attributes-using-cfg_attr.rs | 6 - src/test/run-pass/cfg/cfg-attr-cfg.rs | 8 - src/test/run-pass/cfg/cfg-attr-crate.rs | 8 - src/test/run-pass/cfg/cfg-family.rs | 13 - src/test/run-pass/cfg/cfg-in-crate-1.rs | 5 - src/test/run-pass/cfg/cfg-macros-foo.rs | 26 - src/test/run-pass/cfg/cfg-macros-notfoo.rs | 26 - src/test/run-pass/cfg/cfg-match-arm.rs | 20 - src/test/run-pass/cfg/cfg-target-family.rs | 14 - src/test/run-pass/cfg/cfg-target-vendor.rs | 8 - src/test/run-pass/cfg/cfg_attr.rs | 50 - src/test/run-pass/cfg/cfg_inner_static.rs | 10 - src/test/run-pass/cfg/cfg_stmt_expr.rs | 92 - src/test/run-pass/cfg/cfgs-on-items.rs | 29 - src/test/run-pass/cfg/conditional-compile-arch.rs | 38 - src/test/run-pass/cfg/conditional-compile.rs | 149 - .../cfg/crate-attributes-using-cfg_attr.rs | 6 - src/test/run-pass/chalkify/builtin-copy-clone.rs | 44 - src/test/run-pass/chalkify/inherent_impl.rs | 42 - src/test/run-pass/chalkify/projection.rs | 25 - src/test/run-pass/chalkify/super_trait.rs | 19 - src/test/run-pass/chalkify/trait_implied_bound.rs | 18 - src/test/run-pass/chalkify/type_implied_bound.rs | 29 - src/test/run-pass/char.rs | 13 - src/test/run-pass/char_unicode.rs | 12 - .../run-pass/check-static-recursion-foreign.rs | 26 - src/test/run-pass/check_const-feature-gated.rs | 7 - src/test/run-pass/child-outlives-parent.rs | 13 - src/test/run-pass/cleanup-arm-conditional.rs | 39 - .../run-pass/cleanup-rvalue-during-if-and-while.rs | 43 - src/test/run-pass/cleanup-rvalue-for-scope.rs | 63 - src/test/run-pass/cleanup-rvalue-scopes.rs | 131 - .../cleanup-rvalue-temp-during-incomplete-alloc.rs | 48 - src/test/run-pass/cleanup-shortcircuit.rs | 22 - src/test/run-pass/clone-with-exterior.rs | 22 - .../run-pass/close-over-big-then-small-data.rs | 41 - src/test/run-pass/cmp-default.rs | 73 - src/test/run-pass/codegen-object-shim.rs | 6 - src/test/run-pass/coerce/coerce-expect-unsized.rs | 43 - .../run-pass/coerce/coerce-overloaded-autoderef.rs | 67 - .../run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs | 17 - .../coerce/coerce-reborrow-imm-ptr-rcvr.rs | 18 - .../run-pass/coerce/coerce-reborrow-imm-vec-arg.rs | 19 - .../coerce/coerce-reborrow-imm-vec-rcvr.rs | 16 - .../run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs | 25 - .../coerce/coerce-reborrow-mut-ptr-rcvr.rs | 27 - .../run-pass/coerce/coerce-reborrow-mut-vec-arg.rs | 18 - .../coerce/coerce-reborrow-mut-vec-rcvr.rs | 14 - src/test/run-pass/coerce/coerce-unify-return.rs | 19 - src/test/run-pass/coerce/coerce-unify.rs | 68 - src/test/run-pass/coerce/coerce-unsize-subtype.rs | 40 - .../auxiliary/re_rebalance_coherence_lib.rs | 31 - .../run-pass/coherence/coherence-bigint-int.rs | 16 - .../run-pass/coherence/coherence-bigint-vecint.rs | 16 - src/test/run-pass/coherence/coherence-blanket.rs | 19 - .../coherence/coherence-covered-type-parameter.rs | 17 - .../run-pass/coherence/coherence-impl-in-fn.rs | 17 - .../coherence/coherence-iterator-vec-any-elem.rs | 17 - .../run-pass/coherence/coherence-iterator-vec.rs | 17 - .../coherence/coherence-multidispatch-tuple.rs | 27 - .../coherence/coherence-rfc447-constrained.rs | 25 - .../run-pass/coherence/coherence-where-clause.rs | 41 - src/test/run-pass/coherence/coherence_copy_like.rs | 22 - ...ce-coherence-default-generic-associated-type.rs | 27 - src/test/run-pass/collections-const-new.rs | 15 - src/test/run-pass/command-exec.rs | 104 - src/test/run-pass/command-pre-exec.rs | 118 - src/test/run-pass/command-uid-gid.rs | 32 - src/test/run-pass/complex.rs | 38 - src/test/run-pass/consts/assoc-const.rs | 21 - .../auxiliary/anon-extern-mod-cross-crate-1.rs | 9 - .../run-pass/consts/auxiliary/cci_borrow_lib.rs | 3 - src/test/run-pass/consts/auxiliary/cci_const.rs | 6 - .../run-pass/consts/auxiliary/cci_const_block.rs | 6 - src/test/run-pass/consts/bswap-const.rs | 15 - .../consts/chained-constants-stackoverflow.rs | 356 -- .../run-pass/consts/const-adt-align-mismatch.rs | 22 - src/test/run-pass/consts/const-autoderef.rs | 11 - src/test/run-pass/consts/const-big-enum.rs | 30 - src/test/run-pass/consts/const-binops.rs | 126 - .../consts/const-bitshift-rhs-inference.rs | 24 - .../run-pass/consts/const-block-cross-crate-fn.rs | 9 - .../consts/const-block-item-macro-codegen.rs | 40 - src/test/run-pass/consts/const-block-item.rs | 41 - .../consts/const-block-non-item-statement-3.rs | 8 - src/test/run-pass/consts/const-block.rs | 45 - src/test/run-pass/consts/const-bound.rs | 20 - src/test/run-pass/consts/const-byte-str-cast.rs | 9 - src/test/run-pass/consts/const-cast-ptr-int.rs | 16 - src/test/run-pass/consts/const-cast.rs | 16 - src/test/run-pass/consts/const-const.rs | 9 - src/test/run-pass/consts/const-contents.rs | 19 - .../run-pass/consts/const-cross-crate-const.rs | 16 - .../run-pass/consts/const-cross-crate-extern.rs | 11 - src/test/run-pass/consts/const-deref.rs | 8 - src/test/run-pass/consts/const-endianess.rs | 21 - src/test/run-pass/consts/const-enum-byref-self.rs | 18 - src/test/run-pass/consts/const-enum-byref.rs | 16 - src/test/run-pass/consts/const-enum-cast.rs | 26 - src/test/run-pass/consts/const-enum-ptr.rs | 12 - src/test/run-pass/consts/const-enum-struct.rs | 12 - src/test/run-pass/consts/const-enum-struct2.rs | 12 - src/test/run-pass/consts/const-enum-structlike.rs | 16 - src/test/run-pass/consts/const-enum-tuple.rs | 11 - src/test/run-pass/consts/const-enum-tuple2.rs | 11 - src/test/run-pass/consts/const-enum-tuplestruct.rs | 12 - .../run-pass/consts/const-enum-tuplestruct2.rs | 12 - src/test/run-pass/consts/const-enum-vec-index.rs | 30 - src/test/run-pass/consts/const-enum-vec-ptr.rs | 15 - src/test/run-pass/consts/const-enum-vector.rs | 15 - .../consts/const-expr-in-fixed-length-vec.rs | 12 - .../run-pass/consts/const-expr-in-vec-repeat.rs | 11 - src/test/run-pass/consts/const-extern-function.rs | 16 - .../run-pass/consts/const-fields-and-indexing.rs | 28 - src/test/run-pass/consts/const-fn-const-eval.rs | 10 - src/test/run-pass/consts/const-fn-feature-flags.rs | 13 - src/test/run-pass/consts/const-fn-method.rs | 16 - src/test/run-pass/consts/const-fn-nested.rs | 12 - .../run-pass/consts/const-fn-stability-calls.rs | 27 - src/test/run-pass/consts/const-fn-type-name.rs | 37 - src/test/run-pass/consts/const-fn-val.rs | 15 - src/test/run-pass/consts/const-fn.rs | 42 - .../run-pass/consts/const-index-feature-gate.rs | 7 - .../run-pass/consts/const-int-saturating-arith.rs | 35 - src/test/run-pass/consts/const-meth-pattern.rs | 18 - src/test/run-pass/consts/const-needs_drop.rs | 29 - src/test/run-pass/consts/const-negation.rs | 35 - src/test/run-pass/consts/const-negative.rs | 9 - src/test/run-pass/consts/const-nullary-enum.rs | 23 - .../consts/const-nullary-univariant-enum.rs | 15 - src/test/run-pass/consts/const-pattern-variant.rs | 29 - src/test/run-pass/consts/const-rec-and-tup.rs | 20 - .../run-pass/consts/const-region-ptrs-noncopy.rs | 12 - src/test/run-pass/consts/const-region-ptrs.rs | 15 - src/test/run-pass/consts/const-repeated-values.rs | 10 - src/test/run-pass/consts/const-size_of-align_of.rs | 51 - src/test/run-pass/consts/const-str-ptr.rs | 17 - src/test/run-pass/consts/const-struct-offsets.rs | 18 - src/test/run-pass/consts/const-struct.rs | 32 - src/test/run-pass/consts/const-trait-to-trait.rs | 24 - src/test/run-pass/consts/const-tuple-struct.rs | 14 - src/test/run-pass/consts/const-unit-struct.rs | 12 - src/test/run-pass/consts/const-unsafe-fn.rs | 21 - src/test/run-pass/consts/const-vec-of-fns.rs | 25 - src/test/run-pass/consts/const-vec-syntax.rs | 9 - src/test/run-pass/consts/const-vecs-and-slices.rs | 23 - src/test/run-pass/consts/const.rs | 6 - src/test/run-pass/consts/consts-in-patterns.rs | 18 - src/test/run-pass/consts/deref_in_pattern.rs | 12 - src/test/run-pass/consts/ice-48279.rs | 26 - src/test/run-pass/consts/issue-37550.rs | 12 - src/test/run-pass/consts/issue-broken-mir.rs | 10 - src/test/run-pass/consts/locals-in-const-fn.rs | 35 - src/test/run-pass/consts/match-const-fn-structs.rs | 22 - src/test/run-pass/consts/mozjs-error.rs | 31 - src/test/run-pass/consts/non-scalar-cast.rs | 9 - src/test/run-pass/consts/promotion.rs | 17 - src/test/run-pass/consts/references.rs | 27 - src/test/run-pass/consts/repeat_match.rs | 12 - src/test/run-pass/consts/return-in-const-fn.rs | 10 - src/test/run-pass/consts/signed_enum_discr.rs | 19 - src/test/run-pass/consts/transmute-const.rs | 14 - .../run-pass/consts/tuple-struct-constructors.rs | 10 - src/test/run-pass/core-run-destroy.rs | 87 - src/test/run-pass/crate-leading-sep.rs | 7 - .../run-pass/crate-method-reexport-grrrrrrr.rs | 21 - src/test/run-pass/crate-name-attr-used.rs | 8 - .../cross-crate/anon-extern-mod-cross-crate-2.rs | 14 - .../auxiliary/anon-extern-mod-cross-crate-1.rs | 9 - .../auxiliary/anon_trait_static_method_lib.rs | 9 - .../cross-crate/auxiliary/cci_borrow_lib.rs | 3 - .../cross-crate/auxiliary/cci_capture_clause.rs | 10 - .../run-pass/cross-crate/auxiliary/cci_const.rs | 6 - .../run-pass/cross-crate/auxiliary/cci_impl_lib.rs | 16 - .../run-pass/cross-crate/auxiliary/cci_iter_lib.rs | 11 - .../cross-crate/auxiliary/cci_nested_lib.rs | 52 - .../cross-crate/auxiliary/cci_no_inline_lib.rs | 12 - .../auxiliary/moves_based_on_type_lib.rs | 17 - .../cross-crate/auxiliary/newtype_struct_xc.rs | 3 - .../cross-crate/auxiliary/pub_static_array.rs | 1 - .../auxiliary/reexported_static_methods.rs | 43 - .../auxiliary/xcrate-trait-lifetime-param.rs | 3 - .../auxiliary/xcrate_address_insignificant.rs | 8 - .../auxiliary/xcrate_associated_type_defaults.rs | 12 - .../auxiliary/xcrate_generic_fn_nested_return.rs | 16 - .../auxiliary/xcrate_static_addresses.rs | 17 - .../cross-crate/auxiliary/xcrate_unit_struct.rs | 28 - src/test/run-pass/cross-crate/cci_borrow.rs | 14 - .../run-pass/cross-crate/cci_capture_clause.rs | 14 - src/test/run-pass/cross-crate/cci_impl_exe.rs | 18 - src/test/run-pass/cross-crate/cci_iter_exe.rs | 13 - src/test/run-pass/cross-crate/cci_nested_exe.rs | 20 - src/test/run-pass/cross-crate/cci_no_inline_exe.rs | 23 - .../run-pass/cross-crate/cross-crate-const-pat.rs | 14 - .../cross-crate/cross-crate-newtype-struct-pat.rs | 12 - .../cross-crate/moves-based-on-type-cross-crate.rs | 11 - .../reexported-static-methods-cross-crate.rs | 16 - .../cross-crate/static-array-across-crate.rs | 13 - .../cross-crate/xcrate-address-insignificant.rs | 9 - .../cross-crate/xcrate-associated-type-defaults.rs | 29 - .../cross-crate/xcrate-static-addresses.rs | 13 - .../cross-crate/xcrate-trait-lifetime-param.rs | 19 - .../run-pass/cross-crate/xcrate-unit-struct.rs | 30 - .../cross-crate/xcrate_generic_fn_nested_return.rs | 8 - src/test/run-pass/crt-static-off-works.rs | 10 - src/test/run-pass/crt-static-on-works.rs | 9 - src/test/run-pass/cycle-generic-bound.rs | 11 - src/test/run-pass/dead-code-alias-in-pat.rs | 10 - src/test/run-pass/dead-code-leading-underscore.rs | 31 - src/test/run-pass/debuginfo-lto.rs | 24 - src/test/run-pass/deep.rs | 8 - src/test/run-pass/default-alloc-error-hook.rs | 20 - src/test/run-pass/default-associated-types.rs | 23 - src/test/run-pass/default-method-parsing.rs | 8 - src/test/run-pass/default-method-simple.rs | 26 - src/test/run-pass/defaults-well-formedness.rs | 27 - src/test/run-pass/deprecation-in-force-unstable.rs | 5 - src/test/run-pass/deref-lval.rs | 11 - src/test/run-pass/deref-mut-on-ref.rs | 15 - src/test/run-pass/deref-on-ref.rs | 19 - src/test/run-pass/deref-rc.rs | 8 - src/test/run-pass/deref.rs | 9 - .../run-pass/deriving/auxiliary/derive-no-std.rs | 29 - src/test/run-pass/deriving/derive-no-std.rs | 12 - .../deriving/derive-partialord-correctness.rs | 9 - .../run-pass/deriving/deriving-associated-types.rs | 199 -- src/test/run-pass/deriving/deriving-bounds.rs | 5 - src/test/run-pass/deriving/deriving-clone-array.rs | 10 - src/test/run-pass/deriving/deriving-clone-enum.rs | 14 - .../deriving/deriving-clone-generic-enum.rs | 14 - .../deriving/deriving-clone-generic-struct.rs | 13 - .../deriving-clone-generic-tuple-struct.rs | 9 - .../run-pass/deriving/deriving-clone-struct.rs | 26 - .../deriving/deriving-clone-tuple-struct.rs | 7 - .../run-pass/deriving/deriving-cmp-generic-enum.rs | 44 - .../deriving/deriving-cmp-generic-struct-enum.rs | 48 - .../deriving/deriving-cmp-generic-struct.rs | 40 - .../deriving/deriving-cmp-generic-tuple-struct.rs | 38 - .../run-pass/deriving/deriving-cmp-shortcircuit.rs | 37 - src/test/run-pass/deriving/deriving-copyclone.rs | 38 - src/test/run-pass/deriving/deriving-default-box.rs | 15 - .../deriving/deriving-enum-single-variant.rs | 12 - .../deriving/deriving-eq-ord-boxed-slice.rs | 15 - src/test/run-pass/deriving/deriving-hash.rs | 76 - src/test/run-pass/deriving/deriving-in-fn.rs | 10 - src/test/run-pass/deriving/deriving-in-macro.rs | 16 - .../run-pass/deriving/deriving-meta-multiple.rs | 26 - src/test/run-pass/deriving/deriving-meta.rs | 23 - .../deriving-self-lifetime-totalord-totaleq.rs | 16 - src/test/run-pass/deriving/deriving-show-2.rs | 54 - src/test/run-pass/deriving/deriving-show.rs | 35 - .../deriving/deriving-via-extension-c-enum.rs | 17 - .../deriving/deriving-via-extension-enum.rs | 16 - .../deriving/deriving-via-extension-hash-enum.rs | 17 - .../deriving/deriving-via-extension-hash-struct.rs | 12 - .../deriving-via-extension-struct-empty.rs | 8 - ...iving-via-extension-struct-like-enum-variant.rs | 13 - .../deriving-via-extension-struct-tuple.rs | 17 - .../deriving/deriving-via-extension-struct.rs | 16 - .../deriving/deriving-via-extension-type-params.rs | 16 - .../run-pass/deriving/deriving-with-repr-packed.rs | 36 - src/test/run-pass/dispatch_from_dyn_zst.rs | 51 - .../run-pass/diverging-fallback-control-flow.rs | 101 - .../run-pass/diverging-fallback-method-chain.rs | 20 - src/test/run-pass/diverging-fallback-option.rs | 14 - src/test/run-pass/double-ref.rs | 36 - .../drop/auxiliary/dropck_eyepatch_extern_crate.rs | 50 - src/test/run-pass/drop/drop-on-empty-block-exit.rs | 12 - src/test/run-pass/drop/drop-on-ret.rs | 15 - src/test/run-pass/drop/drop-struct-as-object.rs | 38 - src/test/run-pass/drop/drop-trait-enum.rs | 95 - src/test/run-pass/drop/drop-trait-generic.rs | 15 - src/test/run-pass/drop/drop-trait.rs | 15 - src/test/run-pass/drop/drop-uninhabited-enum.rs | 14 - .../run-pass/drop/drop-with-type-ascription-1.rs | 8 - .../run-pass/drop/drop-with-type-ascription-2.rs | 8 - .../run-pass/drop/dropck-eyepatch-extern-crate.rs | 39 - src/test/run-pass/drop/dropck-eyepatch-reorder.rs | 79 - src/test/run-pass/drop/dropck-eyepatch.rs | 102 - src/test/run-pass/drop/dropck_legal_cycles.rs | 1183 ------- src/test/run-pass/drop/dynamic-drop-async.rs | 328 -- src/test/run-pass/drop/dynamic-drop.rs | 436 --- src/test/run-pass/drop/no-drop-flag-size.rs | 15 - src/test/run-pass/drop/nondrop-cycle.rs | 31 - src/test/run-pass/dupe-first-attr.rc | 24 - src/test/run-pass/duplicated-external-mods.rs | 9 - .../dynamically-sized-types/dst-coerce-custom.rs | 43 - .../dynamically-sized-types/dst-coerce-rc.rs | 42 - .../dynamically-sized-types/dst-coercions.rs | 28 - .../dynamically-sized-types/dst-deref-mut.rs | 35 - .../run-pass/dynamically-sized-types/dst-deref.rs | 30 - .../dynamically-sized-types/dst-field-align.rs | 67 - .../run-pass/dynamically-sized-types/dst-index.rs | 34 - .../dst-irrefutable-bind.rs | 27 - .../run-pass/dynamically-sized-types/dst-raw.rs | 138 - .../dynamically-sized-types/dst-struct-sole.rs | 76 - .../run-pass/dynamically-sized-types/dst-struct.rs | 122 - .../dynamically-sized-types/dst-trait-tuple.rs | 103 - .../run-pass/dynamically-sized-types/dst-trait.rs | 105 - .../dynamically-sized-types/dst-tuple-sole.rs | 79 - .../run-pass/dynamically-sized-types/dst-tuple.rs | 120 - src/test/run-pass/early-ret-binop-add.rs | 11 - src/test/run-pass/early-vtbl-resolution.rs | 19 - src/test/run-pass/edition-keywords-2015-2015.rs | 36 - src/test/run-pass/edition-keywords-2015-2018.rs | 36 - src/test/run-pass/edition-keywords-2018-2015.rs | 34 - src/test/run-pass/edition-keywords-2018-2018.rs | 34 - src/test/run-pass/else-if.rs | 20 - src/test/run-pass/empty-allocation-non-null.rs | 14 - .../run-pass/empty-allocation-rvalue-non-null.rs | 8 - src/test/run-pass/empty-type-parameter-list.rs | 24 - src/test/run-pass/empty_global_asm.rs | 20 - src/test/run-pass/env-args-reverse-iterator.rs | 39 - src/test/run-pass/env-funky-keys.rs | 42 - src/test/run-pass/env-home-dir.rs | 51 - src/test/run-pass/env-null-vars.rs | 23 - src/test/run-pass/env-vars.rs | 13 - src/test/run-pass/epoch-gate-feature.rs | 15 - src/test/run-pass/eq-multidispatch.rs | 30 - src/test/run-pass/estr-uniq.rs | 15 - src/test/run-pass/exec-env.rs | 11 - src/test/run-pass/existential_type.rs | 89 - src/test/run-pass/explicit-i-suffix.rs | 14 - src/test/run-pass/export-glob-imports-target.rs | 22 - src/test/run-pass/export-multi.rs | 12 - src/test/run-pass/export-non-interference2.rs | 11 - src/test/run-pass/export-non-interference3.rs | 11 - src/test/run-pass/expr-block-fn.rs | 9 - src/test/run-pass/expr-block-generic-unique1.rs | 19 - src/test/run-pass/expr-block-generic-unique2.rs | 15 - src/test/run-pass/expr-block-generic.rs | 26 - src/test/run-pass/expr-block-slot.rs | 13 - src/test/run-pass/expr-block-unique.rs | 5 - src/test/run-pass/expr-block.rs | 21 - src/test/run-pass/expr-copy.rs | 18 - src/test/run-pass/expr-empty-ret.rs | 15 - src/test/run-pass/expr-fn.rs | 61 - src/test/run-pass/expr-if-generic.rs | 29 - src/test/run-pass/expr-if-panic-all.rs | 11 - src/test/run-pass/expr-if-panic.rs | 18 - src/test/run-pass/expr-if-unique.rs | 11 - src/test/run-pass/expr-if.rs | 52 - src/test/run-pass/expr-scope.rs | 7 - src/test/run-pass/ext-expand-inner-exprs.rs | 7 - src/test/run-pass/extend-for-unit.rs | 12 - src/test/run-pass/exterior.rs | 24 - .../extern/auxiliary/extern-crosscrate-source.rs | 31 - .../run-pass/extern/auxiliary/extern-take-value.rs | 5 - .../extern/auxiliary/extern_calling_convention.rs | 26 - .../extern/auxiliary/extern_mod_ordering_lib.rs | 5 - src/test/run-pass/extern/auxiliary/fat_drop.rs | 13 - src/test/run-pass/extern/extern-1.rs | 9 - src/test/run-pass/extern/extern-call-deep.rs | 39 - src/test/run-pass/extern/extern-call-deep2.rs | 44 - src/test/run-pass/extern/extern-call-direct.rs | 10 - src/test/run-pass/extern/extern-call-indirect.rs | 38 - src/test/run-pass/extern/extern-call-scrub.rs | 48 - .../extern/extern-calling-convention-test.rs | 12 - .../extern/extern-compare-with-return-type.rs | 25 - src/test/run-pass/extern/extern-crosscrate.rs | 21 - src/test/run-pass/extern/extern-foreign-crate.rs | 6 - src/test/run-pass/extern/extern-methods.rs | 30 - src/test/run-pass/extern/extern-mod-abi.rs | 9 - .../run-pass/extern/extern-mod-ordering-exe.rs | 12 - src/test/run-pass/extern/extern-pass-TwoU16s.rs | 25 - src/test/run-pass/extern/extern-pass-TwoU32s.rs | 25 - src/test/run-pass/extern/extern-pass-TwoU64s.rs | 25 - src/test/run-pass/extern/extern-pass-TwoU8s.rs | 25 - src/test/run-pass/extern/extern-pass-char.rs | 16 - src/test/run-pass/extern/extern-pass-double.rs | 13 - src/test/run-pass/extern/extern-pass-empty.rs | 55 - src/test/run-pass/extern/extern-pass-u32.rs | 16 - src/test/run-pass/extern/extern-pass-u64.rs | 16 - src/test/run-pass/extern/extern-prelude-core.rs | 18 - .../run-pass/extern/extern-prelude-core.stderr | 8 - .../extern/extern-prelude-no-speculative.rs | 13 - src/test/run-pass/extern/extern-prelude-std.rs | 13 - src/test/run-pass/extern/extern-prelude-std.stderr | 8 - src/test/run-pass/extern/extern-pub.rs | 9 - src/test/run-pass/extern/extern-return-TwoU16s.rs | 21 - src/test/run-pass/extern/extern-return-TwoU32s.rs | 21 - src/test/run-pass/extern/extern-return-TwoU64s.rs | 21 - src/test/run-pass/extern/extern-return-TwoU8s.rs | 21 - src/test/run-pass/extern/extern-rust.rs | 12 - src/test/run-pass/extern/extern-take-value.rs | 13 - src/test/run-pass/extern/extern-thiscall.rs | 26 - .../run-pass/extern/extern-types-inherent-impl.rs | 19 - .../extern/extern-types-manual-sync-send.rs | 19 - .../run-pass/extern/extern-types-pointer-cast.rs | 32 - .../run-pass/extern/extern-types-size_of_val.rs | 17 - .../run-pass/extern/extern-types-thin-pointer.rs | 43 - .../run-pass/extern/extern-types-trait-impl.rs | 27 - src/test/run-pass/extern/extern-vectorcall.rs | 26 - src/test/run-pass/extern/extern_fat_drop.rs | 13 - src/test/run-pass/extoption_env-not-defined.rs | 5 - src/test/run-pass/fact.rs | 26 - src/test/run-pass/fat-lto.rs | 7 - src/test/run-pass/fds-are-cloexec.rs | 83 - src/test/run-pass/filter-block-view-items.rs | 8 - src/test/run-pass/fixup-deref-mut.rs | 50 - src/test/run-pass/for-loop-while/auto-loop.rs | 10 - src/test/run-pass/for-loop-while/break-value.rs | 7 - src/test/run-pass/for-loop-while/break.rs | 25 - src/test/run-pass/for-loop-while/for-destruct.rs | 9 - .../run-pass/for-loop-while/for-loop-goofiness.rs | 16 - .../for-loop-while/for-loop-has-unit-body.rs | 13 - .../for-loop-while/for-loop-into-iterator.rs | 19 - .../for-loop-lifetime-of-unbound-values.rs | 34 - src/test/run-pass/for-loop-while/for-loop-macro.rs | 11 - .../for-loop-while/for-loop-mut-ref-element.rs | 6 - .../run-pass/for-loop-while/for-loop-no-std.rs | 14 - src/test/run-pass/for-loop-while/for-loop-panic.rs | 4 - ...loop-unconstrained-element-type-i32-fallback.rs | 11 - .../foreach-external-iterators-break.rs | 13 - ...ach-external-iterators-hashmap-break-restart.rs | 33 - .../foreach-external-iterators-hashmap.rs | 19 - .../foreach-external-iterators-loop.rs | 13 - .../foreach-external-iterators-nested.rs | 15 - .../for-loop-while/foreach-external-iterators.rs | 10 - src/test/run-pass/for-loop-while/foreach-nested.rs | 16 - .../for-loop-while/foreach-put-structured.rs | 22 - .../for-loop-while/foreach-simple-outer-slot.rs | 16 - .../run-pass/for-loop-while/label_break_value.rs | 116 - src/test/run-pass/for-loop-while/labeled-break.rs | 22 - .../run-pass/for-loop-while/linear-for-loop.rs | 23 - .../liveness-assign-imm-local-after-loop.rs | 18 - .../run-pass/for-loop-while/liveness-loop-break.rs | 13 - .../for-loop-while/liveness-move-in-loop.rs | 20 - .../run-pass/for-loop-while/loop-break-cont-1.rs | 9 - .../run-pass/for-loop-while/loop-break-cont.rs | 39 - .../run-pass/for-loop-while/loop-break-value.rs | 138 - src/test/run-pass/for-loop-while/loop-diverges.rs | 14 - .../for-loop-while/loop-label-shadowing.rs | 11 - .../for-loop-while/loop-labeled-break-value.rs | 11 - .../loop-no-reinit-needed-post-bot.rs | 34 - src/test/run-pass/for-loop-while/loop-scope.rs | 8 - src/test/run-pass/for-loop-while/while-cont.rs | 11 - .../run-pass/for-loop-while/while-flow-graph.rs | 6 - src/test/run-pass/for-loop-while/while-label.rs | 15 - src/test/run-pass/for-loop-while/while-let.rs | 46 - .../for-loop-while/while-loop-constraints-2.rs | 15 - .../run-pass/for-loop-while/while-prelude-drop.rs | 24 - .../run-pass/for-loop-while/while-with-break.rs | 17 - src/test/run-pass/for-loop-while/while.rs | 13 - src/test/run-pass/foreign/auxiliary/fn-abi.rs | 2 - src/test/run-pass/foreign/auxiliary/foreign_lib.rs | 38 - .../run-pass/foreign/foreign-call-no-runtime.rs | 55 - src/test/run-pass/foreign/foreign-dupe.rs | 17 - src/test/run-pass/foreign/foreign-fn-linkname.rs | 30 - src/test/run-pass/foreign/foreign-fn-with-byval.rs | 32 - src/test/run-pass/foreign/foreign-int-types.rs | 13 - .../foreign/foreign-mod-src/compiletest-ignore-dir | 0 src/test/run-pass/foreign/foreign-mod-src/inner.rs | 14 - .../run-pass/foreign/foreign-mod-unused-const.rs | 12 - src/test/run-pass/foreign/foreign-no-abi.rs | 22 - .../foreign/foreign-src/compiletest-ignore-dir | 0 src/test/run-pass/foreign/foreign-src/foreign.rs | 9 - .../foreign/foreign-truncated-arguments.rs | 20 - src/test/run-pass/foreign/foreign2.rs | 30 - src/test/run-pass/format-hygiene.rs | 8 - src/test/run-pass/format-nan.rs | 9 - src/test/run-pass/format-no-std.rs | 28 - src/test/run-pass/format-ref-cell.rs | 10 - src/test/run-pass/fsu-moves-and-copies.rs | 95 - src/test/run-pass/fun-call-variants.rs | 12 - src/test/run-pass/fun-indirect-call.rs | 9 - .../functions-closures/auxiliary/fn-abi.rs | 2 - .../call-closure-from-overloaded-op.rs | 9 - .../capture-clauses-boxed-closures.rs | 14 - .../capture-clauses-unboxed-closures.rs | 13 - .../run-pass/functions-closures/clone-closure.rs | 18 - .../closure-bounds-can-capture-chan.rs | 16 - .../closure-expected-type/README.md | 8 - .../expect-infer-supply-two-infers.rs | 19 - .../closure-expected-type/issue-38714.rs | 19 - .../supply-just-return-type.rs | 26 - .../closure-expected-type/supply-nothing.rs | 11 - .../functions-closures/closure-immediate.rs | 13 - .../functions-closures/closure-inference.rs | 11 - .../functions-closures/closure-inference2.rs | 9 - .../run-pass/functions-closures/closure-reform.rs | 56 - .../closure-returning-closure.rs | 5 - .../functions-closures/closure-to-fn-coercion.rs | 35 - .../closure_to_fn_coercion-expected-types.rs | 9 - .../run-pass/functions-closures/copy-closure.rs | 16 - src/test/run-pass/functions-closures/fn-abi.rs | 18 - .../run-pass/functions-closures/fn-bare-assign.rs | 17 - .../functions-closures/fn-bare-coerce-to-block.rs | 10 - .../run-pass/functions-closures/fn-bare-item.rs | 8 - .../run-pass/functions-closures/fn-bare-size.rs | 8 - .../run-pass/functions-closures/fn-bare-spawn.rs | 15 - .../run-pass/functions-closures/fn-coerce-field.rs | 13 - .../functions-closures/fn-item-type-cast.rs | 22 - .../functions-closures/fn-item-type-coerce.rs | 17 - .../functions-closures/fn-item-type-zero-sized.rs | 13 - src/test/run-pass/functions-closures/fn-lval.rs | 11 - .../run-pass/functions-closures/fn-type-infer.rs | 11 - .../implied-bounds-closure-arg-outlives.rs | 35 - .../nullable-pointer-opt-closures.rs | 34 - .../parallel-codegen-closures.rs | 28 - .../functions-closures/return-from-closure.rs | 33 - src/test/run-pass/generator/addassign-yield.rs | 35 - .../generator/auxiliary/xcrate-reachable.rs | 14 - src/test/run-pass/generator/auxiliary/xcrate.rs | 18 - src/test/run-pass/generator/borrow-in-tail-expr.rs | 11 - src/test/run-pass/generator/conditional-drop.rs | 58 - src/test/run-pass/generator/control-flow.rs | 50 - src/test/run-pass/generator/drop-and-replace.rs | 45 - src/test/run-pass/generator/drop-env.rs | 63 - src/test/run-pass/generator/issue-44197.rs | 33 - src/test/run-pass/generator/issue-52398.rs | 28 - src/test/run-pass/generator/issue-57084.rs | 28 - src/test/run-pass/generator/issue-58888.rs | 27 - src/test/run-pass/generator/iterator-count.rs | 44 - .../run-pass/generator/live-upvar-across-yield.rs | 14 - src/test/run-pass/generator/match-bindings.rs | 23 - src/test/run-pass/generator/nested_generators.rs | 21 - src/test/run-pass/generator/non-static-is-unpin.rs | 18 - src/test/run-pass/generator/overlap-locals.rs | 29 - src/test/run-pass/generator/panic-drops.rs | 57 - src/test/run-pass/generator/panic-safe.rs | 30 - src/test/run-pass/generator/pin-box-generator.rs | 13 - src/test/run-pass/generator/reborrow-mut-upvar.rs | 16 - src/test/run-pass/generator/resume-after-return.rs | 28 - src/test/run-pass/generator/size-moved-locals.rs | 76 - src/test/run-pass/generator/smoke.rs | 174 - src/test/run-pass/generator/static-generators.rs | 20 - .../generator/too-live-local-in-immovable-gen.rs | 21 - src/test/run-pass/generator/xcrate-reachable.rs | 14 - src/test/run-pass/generator/xcrate.rs | 30 - src/test/run-pass/generator/yield-in-args-rev.rs | 19 - src/test/run-pass/generator/yield-in-box.rs | 18 - .../run-pass/generator/yield-in-initializer.rs | 17 - src/test/run-pass/generator/yield-subtype.rs | 17 - .../generics/auxiliary/default_type_params_xc.rs | 5 - src/test/run-pass/generics/generic-alias-unique.rs | 11 - .../generic-default-type-params-cross-crate.rs | 17 - .../generics/generic-default-type-params.rs | 53 - src/test/run-pass/generics/generic-derived-type.rs | 21 - .../run-pass/generics/generic-exterior-unique.rs | 12 - .../run-pass/generics/generic-extern-mangle.rs | 9 - src/test/run-pass/generics/generic-fn-infer.rs | 10 - src/test/run-pass/generics/generic-fn-twice.rs | 11 - src/test/run-pass/generics/generic-fn-unique.rs | 6 - src/test/run-pass/generics/generic-fn.rs | 28 - src/test/run-pass/generics/generic-ivec-leak.rs | 5 - .../run-pass/generics/generic-newtype-struct.rs | 8 - src/test/run-pass/generics/generic-object.rs | 22 - .../run-pass/generics/generic-recursive-tag.rs | 13 - .../run-pass/generics/generic-static-methods.rs | 21 - .../run-pass/generics/generic-tag-corruption.rs | 10 - src/test/run-pass/generics/generic-tag-local.rs | 8 - src/test/run-pass/generics/generic-tag-match.rs | 13 - src/test/run-pass/generics/generic-tag-values.rs | 20 - src/test/run-pass/generics/generic-tag.rs | 15 - src/test/run-pass/generics/generic-temporary.rs | 16 - src/test/run-pass/generics/generic-tup.rs | 8 - src/test/run-pass/generics/generic-type-synonym.rs | 15 - src/test/run-pass/generics/generic-type.rs | 11 - src/test/run-pass/generics/generic-unique.rs | 12 - src/test/run-pass/global-scope.rs | 13 - src/test/run-pass/guards-not-exhaustive.rs | 18 - src/test/run-pass/guards.rs | 20 - src/test/run-pass/hashmap-memory.rs | 94 - src/test/run-pass/hello.rs | 5 - .../hrtb-binder-levels-in-object-types.rs | 29 - .../hrtb-debruijn-object-types-in-closures.rs | 16 - .../hrtb-fn-like-trait-object.rs | 27 - .../higher-rank-trait-bounds/hrtb-fn-like-trait.rs | 27 - .../higher-rank-trait-bounds/hrtb-opt-in-copy.rs | 28 - .../higher-rank-trait-bounds/hrtb-parse.rs | 36 - .../hrtb-precedence-of-plus-where-clause.rs | 25 - .../hrtb-precedence-of-plus.rs | 13 - .../hrtb-resolve-lifetime.rs | 14 - .../hrtb-trait-object-paren-notation.rs | 26 - .../hrtb-trait-object-passed-to-closure.rs | 25 - .../higher-rank-trait-bounds/hrtb-type-outlives.rs | 48 - .../hrtb-unboxed-closure-trait.rs | 11 - src/test/run-pass/html-literals.rs | 94 - src/test/run-pass/if-bot.rs | 6 - src/test/run-pass/if-check.rs | 17 - src/test/run-pass/if-ret.rs | 8 - src/test/run-pass/if-ret.stderr | 8 - src/test/run-pass/ifmt.rs | 323 -- src/test/run-pass/ignore-all-the-things.rs | 47 - src/test/run-pass/impl-for-never.rs | 26 - src/test/run-pass/impl-inherent-non-conflict.rs | 23 - src/test/run-pass/impl-not-adjacent-to-type.rs | 16 - src/test/run-pass/impl-privacy-xc-1.rs | 11 - src/test/run-pass/impl-privacy-xc-2.rs | 10 - src/test/run-pass/impl-trait-in-bindings.rs | 49 - src/test/run-pass/impl-trait-in-bindings.stderr | 6 - src/test/run-pass/impl-trait/auxiliary/xcrate.rs | 23 - src/test/run-pass/impl-trait/bounds_regression.rs | 24 - src/test/run-pass/impl-trait/example-calendar.rs | 857 ----- src/test/run-pass/impl-trait/example-st.rs | 30 - src/test/run-pass/impl-trait/lifetimes.rs | 123 - src/test/run-pass/impl-trait/nesting.rs | 15 - .../run-pass/impl-trait/universal_hrtb_anon.rs | 10 - .../run-pass/impl-trait/universal_hrtb_named.rs | 10 - .../impl-trait/universal_in_adt_in_parameters.rs | 22 - .../universal_in_impl_trait_in_parameters.rs | 30 - .../universal_in_trait_defn_parameters.rs | 18 - .../impl-trait/universal_multiple_bounds.rs | 13 - src/test/run-pass/impl-trait/xcrate.rs | 11 - src/test/run-pass/impl-trait/xcrate_simple.rs | 9 - .../auxiliary/crate_with_invalid_spans.rs | 20 - .../auxiliary/crate_with_invalid_spans_macros.rs | 7 - .../import-crate-with-invalid-spans/main.rs | 13 - src/test/run-pass/imports/import-from.rs | 11 - src/test/run-pass/imports/import-glob-1.rs | 27 - src/test/run-pass/imports/import-glob-crate.rs | 19 - src/test/run-pass/imports/import-in-block.rs | 13 - src/test/run-pass/imports/import-prefix-macro.rs | 27 - src/test/run-pass/imports/import-rename.rs | 13 - src/test/run-pass/imports/import-trailing-comma.rs | 13 - src/test/run-pass/imports/import.rs | 12 - src/test/run-pass/imports/import2.rs | 9 - src/test/run-pass/imports/import3.rs | 13 - src/test/run-pass/imports/import4.rs | 9 - src/test/run-pass/imports/import5.rs | 10 - src/test/run-pass/imports/import6.rs | 15 - src/test/run-pass/imports/import7.rs | 18 - src/test/run-pass/imports/import8.rs | 10 - src/test/run-pass/imports/imports.rs | 66 - src/test/run-pass/in-band-lifetimes.rs | 96 - src/test/run-pass/inc-range-pat.rs | 12 - src/test/run-pass/infer-fn-tail-expr.rs | 11 - src/test/run-pass/inherit-env.rs | 26 - src/test/run-pass/init-large-type.rs | 26 - src/test/run-pass/init-res-into-things.rs | 82 - src/test/run-pass/inlined-main.rs | 4 - src/test/run-pass/inner-attrs-on-impl.rs | 24 - src/test/run-pass/inner-module.rs | 10 - src/test/run-pass/inner-static.rs | 14 - src/test/run-pass/instantiable.rs | 17 - .../run-pass/intrinsics/auxiliary/cci_intrinsic.rs | 14 - .../run-pass/intrinsics/intrinsic-alignment.rs | 74 - src/test/run-pass/intrinsics/intrinsic-assume.rs | 17 - .../run-pass/intrinsics/intrinsic-atomics-cc.rs | 12 - src/test/run-pass/intrinsics/intrinsic-atomics.rs | 103 - .../intrinsics/intrinsic-move-val-cleanups.rs | 190 -- src/test/run-pass/intrinsics/intrinsic-move-val.rs | 82 - .../run-pass/intrinsics/intrinsic-unreachable.rs | 17 - src/test/run-pass/intrinsics/intrinsics-integer.rs | 172 - src/test/run-pass/intrinsics/intrinsics-math.rs | 60 - src/test/run-pass/invalid_const_promotion.rs | 56 - src/test/run-pass/invoke-external-foreign.rs | 17 - src/test/run-pass/irrefutable-unit.rs | 6 - src/test/run-pass/issue-59020.rs | 28 - src/test/run-pass/issues/.gitattributes | 1 - src/test/run-pass/issues/auxiliary/cgu_test.rs | 6 - src/test/run-pass/issues/auxiliary/cgu_test_a.rs | 15 - src/test/run-pass/issues/auxiliary/cgu_test_b.rs | 15 - src/test/run-pass/issues/auxiliary/i8.rs | 3 - src/test/run-pass/issues/auxiliary/iss.rs | 12 - src/test/run-pass/issues/auxiliary/issue-10028.rs | 9 - .../run-pass/issues/auxiliary/issue-10031-aux.rs | 1 - src/test/run-pass/issues/auxiliary/issue-11224.rs | 16 - .../run-pass/issues/auxiliary/issue-11225-1.rs | 18 - .../run-pass/issues/auxiliary/issue-11225-2.rs | 28 - .../run-pass/issues/auxiliary/issue-11225-3.rs | 28 - src/test/run-pass/issues/auxiliary/issue-11508.rs | 10 - src/test/run-pass/issues/auxiliary/issue-11529.rs | 1 - .../run-pass/issues/auxiliary/issue-12133-dylib.rs | 1 - .../issues/auxiliary/issue-12133-dylib2.rs | 6 - .../run-pass/issues/auxiliary/issue-12133-rlib.rs | 3 - .../run-pass/issues/auxiliary/issue-12612-1.rs | 3 - .../run-pass/issues/auxiliary/issue-12612-2.rs | 1 - .../run-pass/issues/auxiliary/issue-12660-aux.rs | 11 - src/test/run-pass/issues/auxiliary/issue-13507.rs | 87 - .../run-pass/issues/auxiliary/issue-13620-1.rs | 9 - .../run-pass/issues/auxiliary/issue-13620-2.rs | 3 - .../run-pass/issues/auxiliary/issue-13872-1.rs | 1 - .../run-pass/issues/auxiliary/issue-13872-2.rs | 3 - .../run-pass/issues/auxiliary/issue-13872-3.rs | 9 - .../run-pass/issues/auxiliary/issue-14344-1.rs | 5 - .../run-pass/issues/auxiliary/issue-14344-2.rs | 3 - src/test/run-pass/issues/auxiliary/issue-14421.rs | 25 - src/test/run-pass/issues/auxiliary/issue-14422.rs | 25 - src/test/run-pass/issues/auxiliary/issue-15562.rs | 5 - src/test/run-pass/issues/auxiliary/issue-16643.rs | 19 - src/test/run-pass/issues/auxiliary/issue-17662.rs | 12 - .../run-pass/issues/auxiliary/issue-17718-aux.rs | 10 - src/test/run-pass/issues/auxiliary/issue-18501.rs | 17 - src/test/run-pass/issues/auxiliary/issue-18514.rs | 17 - src/test/run-pass/issues/auxiliary/issue-18711.rs | 5 - .../run-pass/issues/auxiliary/issue-18913-1.rs | 6 - .../run-pass/issues/auxiliary/issue-18913-2.rs | 6 - src/test/run-pass/issues/auxiliary/issue-19293.rs | 4 - .../run-pass/issues/auxiliary/issue-19340-1.rs | 3 - src/test/run-pass/issues/auxiliary/issue-20389.rs | 4 - .../run-pass/issues/auxiliary/issue-2170-lib.rs | 18 - src/test/run-pass/issues/auxiliary/issue-2316-a.rs | 3 - src/test/run-pass/issues/auxiliary/issue-2316-b.rs | 11 - src/test/run-pass/issues/auxiliary/issue-2380.rs | 15 - src/test/run-pass/issues/auxiliary/issue-2414-a.rs | 12 - src/test/run-pass/issues/auxiliary/issue-2414-b.rs | 4 - src/test/run-pass/issues/auxiliary/issue-2472-b.rs | 13 - .../run-pass/issues/auxiliary/issue-25185-1.rs | 8 - .../run-pass/issues/auxiliary/issue-25185-2.rs | 3 - src/test/run-pass/issues/auxiliary/issue-2526.rs | 44 - src/test/run-pass/issues/auxiliary/issue-25467.rs | 10 - src/test/run-pass/issues/auxiliary/issue-2631-a.rs | 14 - src/test/run-pass/issues/auxiliary/issue-2723-a.rs | 3 - src/test/run-pass/issues/auxiliary/issue-29485.rs | 16 - src/test/run-pass/issues/auxiliary/issue-3012-1.rs | 20 - src/test/run-pass/issues/auxiliary/issue-3136-a.rc | 4 - src/test/run-pass/issues/auxiliary/issue-3136-a.rs | 14 - .../run-pass/issues/auxiliary/issue-31702-1.rs | 16 - .../run-pass/issues/auxiliary/issue-31702-2.rs | 20 - .../run-pass/issues/auxiliary/issue-34796-aux.rs | 20 - src/test/run-pass/issues/auxiliary/issue-36954.rs | 7 - src/test/run-pass/issues/auxiliary/issue-38190.rs | 2 - .../run-pass/issues/auxiliary/issue-38226-aux.rs | 23 - .../issues/auxiliary/issue-38715-modern.rs | 7 - src/test/run-pass/issues/auxiliary/issue-38715.rs | 7 - .../run-pass/issues/auxiliary/issue-3979-traits.rs | 15 - src/test/run-pass/issues/auxiliary/issue-39823.rs | 7 - src/test/run-pass/issues/auxiliary/issue-40469.rs | 1 - src/test/run-pass/issues/auxiliary/issue-41053.rs | 1 - src/test/run-pass/issues/auxiliary/issue-41394.rs | 16 - .../run-pass/issues/auxiliary/issue-42007-s.rs | 4 - .../run-pass/issues/auxiliary/issue-4208-cc.rs | 10 - src/test/run-pass/issues/auxiliary/issue-4545.rs | 2 - .../run-pass/issues/auxiliary/issue-48984-aux.rs | 6 - src/test/run-pass/issues/auxiliary/issue-5518.rs | 4 - src/test/run-pass/issues/auxiliary/issue-5521.rs | 3 - src/test/run-pass/issues/auxiliary/issue-7178.rs | 7 - src/test/run-pass/issues/auxiliary/issue-7899.rs | 1 - src/test/run-pass/issues/auxiliary/issue-8044.rs | 15 - src/test/run-pass/issues/auxiliary/issue-8259.rs | 4 - src/test/run-pass/issues/auxiliary/issue-8401.rs | 16 - src/test/run-pass/issues/auxiliary/issue-9123.rs | 9 - src/test/run-pass/issues/auxiliary/issue-9155.rs | 7 - src/test/run-pass/issues/auxiliary/issue-9188.rs | 13 - src/test/run-pass/issues/auxiliary/issue-9906.rs | 15 - src/test/run-pass/issues/auxiliary/issue-9968.rs | 22 - src/test/run-pass/issues/issue-10025.rs | 11 - src/test/run-pass/issues/issue-10028.rs | 21 - src/test/run-pass/issues/issue-10031.rs | 9 - src/test/run-pass/issues/issue-10228.rs | 20 - src/test/run-pass/issues/issue-10392.rs | 30 - src/test/run-pass/issues/issue-10436.rs | 11 - src/test/run-pass/issues/issue-10626.rs | 27 - src/test/run-pass/issues/issue-10638.rs | 11 - src/test/run-pass/issues/issue-10682.rs | 15 - src/test/run-pass/issues/issue-10683.rs | 11 - src/test/run-pass/issues/issue-10718.rs | 11 - src/test/run-pass/issues/issue-10734.rs | 36 - src/test/run-pass/issues/issue-10767.rs | 10 - src/test/run-pass/issues/issue-10802.rs | 46 - src/test/run-pass/issues/issue-10806.rs | 38 - src/test/run-pass/issues/issue-11047.rs | 26 - src/test/run-pass/issues/issue-11085.rs | 46 - src/test/run-pass/issues/issue-1112.rs | 37 - src/test/run-pass/issues/issue-11205.rs | 85 - src/test/run-pass/issues/issue-11224.rs | 8 - src/test/run-pass/issues/issue-11225-1.rs | 11 - src/test/run-pass/issues/issue-11225-2.rs | 11 - src/test/run-pass/issues/issue-11225-3.rs | 11 - src/test/run-pass/issues/issue-11267.rs | 19 - src/test/run-pass/issues/issue-11382.rs | 4 - src/test/run-pass/issues/issue-11508.rs | 11 - src/test/run-pass/issues/issue-11529.rs | 11 - src/test/run-pass/issues/issue-11552.rs | 22 - src/test/run-pass/issues/issue-11577.rs | 18 - src/test/run-pass/issues/issue-11677.rs | 23 - src/test/run-pass/issues/issue-11709.rs | 38 - src/test/run-pass/issues/issue-11820.rs | 12 - src/test/run-pass/issues/issue-11940.rs | 11 - src/test/run-pass/issues/issue-11958.rs | 10 - src/test/run-pass/issues/issue-12033.rs | 7 - src/test/run-pass/issues/issue-12133-1.rs | 10 - src/test/run-pass/issues/issue-12133-2.rs | 11 - src/test/run-pass/issues/issue-12133-3.rs | 14 - src/test/run-pass/issues/issue-12285.rs | 14 - src/test/run-pass/issues/issue-1257.rs | 11 - src/test/run-pass/issues/issue-12582.rs | 21 - src/test/run-pass/issues/issue-12612.rs | 15 - src/test/run-pass/issues/issue-12660.rs | 14 - src/test/run-pass/issues/issue-12677.rs | 9 - src/test/run-pass/issues/issue-12699.rs | 10 - src/test/run-pass/issues/issue-12744.rs | 5 - src/test/run-pass/issues/issue-12860.rs | 49 - src/test/run-pass/issues/issue-12909.rs | 20 - src/test/run-pass/issues/issue-13027.rs | 178 - src/test/run-pass/issues/issue-13204.rs | 25 - .../issues/issue-13259-windows-tcb-trash.rs | 42 - src/test/run-pass/issues/issue-13264.rs | 74 - src/test/run-pass/issues/issue-13304.rs | 40 - src/test/run-pass/issues/issue-13323.rs | 59 - src/test/run-pass/issues/issue-13434.rs | 21 - src/test/run-pass/issues/issue-13507-2.rs | 36 - src/test/run-pass/issues/issue-13620.rs | 11 - src/test/run-pass/issues/issue-13655.rs | 32 - src/test/run-pass/issues/issue-13665.rs | 15 - src/test/run-pass/issues/issue-13763.rs | 15 - src/test/run-pass/issues/issue-13808.rs | 18 - src/test/run-pass/issues/issue-13867.rs | 49 - src/test/run-pass/issues/issue-13872.rs | 12 - src/test/run-pass/issues/issue-13902.rs | 16 - src/test/run-pass/issues/issue-14229.rs | 21 - src/test/run-pass/issues/issue-14308.rs | 15 - src/test/run-pass/issues/issue-14344.rs | 11 - src/test/run-pass/issues/issue-14382.rs | 15 - src/test/run-pass/issues/issue-14393.rs | 10 - src/test/run-pass/issues/issue-14399.rs | 20 - src/test/run-pass/issues/issue-14421.rs | 16 - src/test/run-pass/issues/issue-14422.rs | 16 - src/test/run-pass/issues/issue-14456.rs | 38 - src/test/run-pass/issues/issue-1451.rs | 27 - src/test/run-pass/issues/issue-14589.rs | 24 - src/test/run-pass/issues/issue-1460.rs | 7 - src/test/run-pass/issues/issue-14821.rs | 21 - src/test/run-pass/issues/issue-14865.rs | 23 - src/test/run-pass/issues/issue-14875.rs | 35 - src/test/run-pass/issues/issue-14919.rs | 55 - src/test/run-pass/issues/issue-14940.rs | 20 - src/test/run-pass/issues/issue-14958.rs | 31 - src/test/run-pass/issues/issue-15043.rs | 14 - src/test/run-pass/issues/issue-15063.rs | 12 - src/test/run-pass/issues/issue-15080.rs | 23 - src/test/run-pass/issues/issue-15104.rs | 14 - src/test/run-pass/issues/issue-15155.rs | 21 - src/test/run-pass/issues/issue-15189.rs | 10 - src/test/run-pass/issues/issue-15221.rs | 16 - src/test/run-pass/issues/issue-15444.rs | 23 - src/test/run-pass/issues/issue-15487.rs | 13 - src/test/run-pass/issues/issue-15523-big.rs | 39 - src/test/run-pass/issues/issue-15523.rs | 42 - src/test/run-pass/issues/issue-15562.rs | 19 - src/test/run-pass/issues/issue-15571.rs | 58 - src/test/run-pass/issues/issue-15673.rs | 9 - src/test/run-pass/issues/issue-15689-1.rs | 10 - src/test/run-pass/issues/issue-15730.rs | 9 - src/test/run-pass/issues/issue-15734.rs | 58 - src/test/run-pass/issues/issue-15763.rs | 89 - src/test/run-pass/issues/issue-15774.rs | 25 - src/test/run-pass/issues/issue-15793.rs | 27 - src/test/run-pass/issues/issue-15858.rs | 33 - .../issues/issue-15881-model-lexer-dotdotdot.rs | 38 - src/test/run-pass/issues/issue-16151.rs | 29 - src/test/run-pass/issues/issue-16256.rs | 7 - src/test/run-pass/issues/issue-16272.rs | 24 - src/test/run-pass/issues/issue-16278.rs | 10 - src/test/run-pass/issues/issue-16441.rs | 11 - src/test/run-pass/issues/issue-16452.rs | 10 - src/test/run-pass/issues/issue-16492.rs | 67 - src/test/run-pass/issues/issue-16530.rs | 15 - src/test/run-pass/issues/issue-16560.rs | 18 - src/test/run-pass/issues/issue-16597-empty.rs | 5 - src/test/run-pass/issues/issue-16597.rs | 10 - src/test/run-pass/issues/issue-1660.rs | 8 - src/test/run-pass/issues/issue-16602-1.rs | 6 - src/test/run-pass/issues/issue-16602-2.rs | 12 - src/test/run-pass/issues/issue-16602-3.rs | 27 - src/test/run-pass/issues/issue-16643.rs | 10 - src/test/run-pass/issues/issue-16648.rs | 11 - src/test/run-pass/issues/issue-16671.rs | 12 - src/test/run-pass/issues/issue-16739.rs | 50 - src/test/run-pass/issues/issue-16745.rs | 11 - src/test/run-pass/issues/issue-16774.rs | 46 - src/test/run-pass/issues/issue-16783.rs | 8 - src/test/run-pass/issues/issue-16819.rs | 12 - src/test/run-pass/issues/issue-1696.rs | 8 - src/test/run-pass/issues/issue-1701.rs | 26 - src/test/run-pass/issues/issue-17068.rs | 12 - src/test/run-pass/issues/issue-17074.rs | 15 - src/test/run-pass/issues/issue-17170.rs | 11 - src/test/run-pass/issues/issue-17216.rs | 21 - src/test/run-pass/issues/issue-17233.rs | 17 - src/test/run-pass/issues/issue-17302.rs | 26 - src/test/run-pass/issues/issue-17322.rs | 15 - src/test/run-pass/issues/issue-17351.rs | 10 - src/test/run-pass/issues/issue-17361.rs | 9 - src/test/run-pass/issues/issue-17503.rs | 10 - src/test/run-pass/issues/issue-17662.rs | 17 - .../run-pass/issues/issue-17718-borrow-interior.rs | 19 - .../run-pass/issues/issue-17718-parse-const.rs | 7 - .../issues/issue-17718-static-unsafe-interior.rs | 52 - src/test/run-pass/issues/issue-17718.rs | 75 - src/test/run-pass/issues/issue-17734.rs | 15 - src/test/run-pass/issues/issue-17756.rs | 8 - src/test/run-pass/issues/issue-17771.rs | 21 - src/test/run-pass/issues/issue-17816.rs | 10 - src/test/run-pass/issues/issue-17877.rs | 14 - src/test/run-pass/issues/issue-17897.rs | 8 - src/test/run-pass/issues/issue-18060.rs | 8 - src/test/run-pass/issues/issue-18075.rs | 7 - src/test/run-pass/issues/issue-18110.rs | 7 - src/test/run-pass/issues/issue-18173.rs | 12 - src/test/run-pass/issues/issue-18232.rs | 22 - src/test/run-pass/issues/issue-18352.rs | 14 - src/test/run-pass/issues/issue-18353.rs | 15 - src/test/run-pass/issues/issue-18412.rs | 26 - src/test/run-pass/issues/issue-18425.rs | 9 - src/test/run-pass/issues/issue-18464.rs | 12 - src/test/run-pass/issues/issue-18501.rs | 13 - src/test/run-pass/issues/issue-18514.rs | 16 - src/test/run-pass/issues/issue-18539.rs | 16 - src/test/run-pass/issues/issue-18652.rs | 10 - src/test/run-pass/issues/issue-18655.rs | 22 - src/test/run-pass/issues/issue-18661.rs | 19 - src/test/run-pass/issues/issue-18685.rs | 21 - src/test/run-pass/issues/issue-18711.rs | 12 - src/test/run-pass/issues/issue-18767.rs | 10 - .../run-pass/issues/issue-18804/auxiliary/lib.rs | 10 - src/test/run-pass/issues/issue-18804/main.rs | 19 - src/test/run-pass/issues/issue-18845.rs | 16 - src/test/run-pass/issues/issue-18859.rs | 16 - src/test/run-pass/issues/issue-18913.rs | 9 - src/test/run-pass/issues/issue-18937-1.rs | 21 - src/test/run-pass/issues/issue-18952.rs | 56 - src/test/run-pass/issues/issue-19001.rs | 11 - src/test/run-pass/issues/issue-19127.rs | 10 - src/test/run-pass/issues/issue-19135.rs | 13 - src/test/run-pass/issues/issue-19244.rs | 34 - src/test/run-pass/issues/issue-19293.rs | 10 - src/test/run-pass/issues/issue-19340-1.rs | 17 - src/test/run-pass/issues/issue-19340-2.rs | 24 - src/test/run-pass/issues/issue-19358.rs | 20 - src/test/run-pass/issues/issue-19367.rs | 32 - src/test/run-pass/issues/issue-19499.rs | 15 - src/test/run-pass/issues/issue-1974.rs | 11 - .../run-pass/issues/issue-19811-escape-unicode.rs | 9 - src/test/run-pass/issues/issue-20055-box-trait.rs | 41 - .../issues/issue-20055-box-unsized-array.rs | 29 - src/test/run-pass/issues/issue-20174.rs | 7 - src/test/run-pass/issues/issue-20343.rs | 32 - src/test/run-pass/issues/issue-20389.rs | 15 - src/test/run-pass/issues/issue-20427.rs | 88 - src/test/run-pass/issues/issue-20544.rs | 18 - src/test/run-pass/issues/issue-20575.rs | 10 - src/test/run-pass/issues/issue-20616.rs | 44 - src/test/run-pass/issues/issue-2063.rs | 22 - src/test/run-pass/issues/issue-20676.rs | 12 - src/test/run-pass/issues/issue-2074.rs | 16 - src/test/run-pass/issues/issue-20803.rs | 10 - src/test/run-pass/issues/issue-20823.rs | 5 - src/test/run-pass/issues/issue-20847.rs | 12 - src/test/run-pass/issues/issue-20953.rs | 12 - src/test/run-pass/issues/issue-21033.rs | 49 - src/test/run-pass/issues/issue-21058.rs | 64 - src/test/run-pass/issues/issue-21291.rs | 10 - src/test/run-pass/issues/issue-21306.rs | 9 - src/test/run-pass/issues/issue-21361.rs | 11 - src/test/run-pass/issues/issue-21384.rs | 21 - src/test/run-pass/issues/issue-21400.rs | 56 - src/test/run-pass/issues/issue-21475.rs | 19 - src/test/run-pass/issues/issue-21486.rs | 77 - src/test/run-pass/issues/issue-21655.rs | 12 - src/test/run-pass/issues/issue-2170-exe.rs | 9 - src/test/run-pass/issues/issue-21721.rs | 9 - src/test/run-pass/issues/issue-2190-1.rs | 26 - src/test/run-pass/issues/issue-21909.rs | 15 - src/test/run-pass/issues/issue-21922.rs | 17 - src/test/run-pass/issues/issue-22008.rs | 9 - src/test/run-pass/issues/issue-22036.rs | 25 - src/test/run-pass/issues/issue-2214.rs | 41 - src/test/run-pass/issues/issue-2216.rs | 24 - src/test/run-pass/issues/issue-22258.rs | 10 - src/test/run-pass/issues/issue-22346.rs | 11 - src/test/run-pass/issues/issue-22403.rs | 6 - src/test/run-pass/issues/issue-22426.rs | 9 - src/test/run-pass/issues/issue-22463.rs | 20 - .../issues/issue-22536-copy-mustnt-zero.rs | 28 - src/test/run-pass/issues/issue-22546.rs | 52 - src/test/run-pass/issues/issue-22577.rs | 27 - src/test/run-pass/issues/issue-22629.rs | 14 - src/test/run-pass/issues/issue-22828.rs | 23 - src/test/run-pass/issues/issue-2284.rs | 14 - src/test/run-pass/issues/issue-22864-1.rs | 7 - src/test/run-pass/issues/issue-22864-2.rs | 7 - src/test/run-pass/issues/issue-2288.rs | 35 - src/test/run-pass/issues/issue-22992-2.rs | 18 - src/test/run-pass/issues/issue-22992.rs | 76 - src/test/run-pass/issues/issue-23036.rs | 11 - src/test/run-pass/issues/issue-2316-c.rs | 12 - src/test/run-pass/issues/issue-23208.rs | 26 - src/test/run-pass/issues/issue-23261.rs | 61 - src/test/run-pass/issues/issue-23304-1.rs | 25 - src/test/run-pass/issues/issue-23304-2.rs | 13 - src/test/run-pass/issues/issue-23311.rs | 12 - src/test/run-pass/issues/issue-23336.rs | 11 - .../issues/issue-23338-ensure-param-drop-order.rs | 164 - .../issue-23338-params-outlive-temps-of-body.rs | 30 - src/test/run-pass/issues/issue-23433.rs | 13 - src/test/run-pass/issues/issue-23485.rs | 50 - src/test/run-pass/issues/issue-23491.rs | 9 - .../issues/issue-23611-enum-swap-in-drop.rs | 258 -- src/test/run-pass/issues/issue-23649-1.rs | 12 - src/test/run-pass/issues/issue-23649-2.rs | 11 - src/test/run-pass/issues/issue-23699.rs | 14 - src/test/run-pass/issues/issue-23781.rs | 29 - src/test/run-pass/issues/issue-2380-b.rs | 10 - src/test/run-pass/issues/issue-23808.rs | 59 - src/test/run-pass/issues/issue-23825.rs | 21 - src/test/run-pass/issues/issue-2383.rs | 9 - src/test/run-pass/issues/issue-23833.rs | 17 - src/test/run-pass/issues/issue-23891.rs | 11 - src/test/run-pass/issues/issue-23898.rs | 10 - src/test/run-pass/issues/issue-23958.rs | 13 - .../issues/issue-23968-const-not-overflow.rs | 12 - src/test/run-pass/issues/issue-23992.rs | 19 - src/test/run-pass/issues/issue-24010.rs | 14 - src/test/run-pass/issues/issue-24086.rs | 23 - src/test/run-pass/issues/issue-2414-c.rs | 9 - src/test/run-pass/issues/issue-2428.rs | 14 - src/test/run-pass/issues/issue-24308.rs | 17 - src/test/run-pass/issues/issue-24313.rs | 33 - src/test/run-pass/issues/issue-24353.rs | 8 - src/test/run-pass/issues/issue-2445-b.rs | 31 - src/test/run-pass/issues/issue-2445.rs | 29 - src/test/run-pass/issues/issue-24533.rs | 24 - ...ue-24535-allow-mutable-borrow-in-match-guard.rs | 57 - src/test/run-pass/issues/issue-24589.rs | 17 - src/test/run-pass/issues/issue-2463.rs | 25 - .../auxiliary/issue-24687-lib.rs | 10 - .../auxiliary/issue-24687-mbcs-in-comments.rs | 27 - .../issues/issue-24687-embed-debuginfo/main.rs | 13 - src/test/run-pass/issues/issue-2472.rs | 14 - src/test/run-pass/issues/issue-24779.rs | 4 - .../run-pass/issues/issue-24805-dropck-itemless.rs | 77 - .../issues/issue-24945-repeat-dash-opts.rs | 9 - src/test/run-pass/issues/issue-24947.rs | 25 - src/test/run-pass/issues/issue-24954.rs | 13 - src/test/run-pass/issues/issue-25089.rs | 33 - src/test/run-pass/issues/issue-25145.rs | 13 - src/test/run-pass/issues/issue-25185.rs | 13 - src/test/run-pass/issues/issue-2526-a.rs | 11 - src/test/run-pass/issues/issue-25279.rs | 16 - src/test/run-pass/issues/issue-25339.rs | 31 - src/test/run-pass/issues/issue-25343.rs | 22 - src/test/run-pass/issues/issue-25467.rs | 12 - src/test/run-pass/issues/issue-25497.rs | 19 - src/test/run-pass/issues/issue-2550.rs | 22 - src/test/run-pass/issues/issue-25515.rs | 20 - .../run-pass/issues/issue-25549-multiple-drop.rs | 33 - src/test/run-pass/issues/issue-25679.rs | 19 - src/test/run-pass/issues/issue-25693.rs | 22 - src/test/run-pass/issues/issue-25700-1.rs | 13 - src/test/run-pass/issues/issue-25700-2.rs | 22 - .../run-pass/issues/issue-25746-bool-transmute.rs | 11 - src/test/run-pass/issues/issue-25757.rs | 18 - src/test/run-pass/issues/issue-25810.rs | 28 - src/test/run-pass/issues/issue-25916.rs | 28 - src/test/run-pass/issues/issue-26127.rs | 12 - src/test/run-pass/issues/issue-26251.rs | 13 - src/test/run-pass/issues/issue-2631-b.rs | 17 - src/test/run-pass/issues/issue-26322.rs | 30 - src/test/run-pass/issues/issue-2633-2.rs | 14 - src/test/run-pass/issues/issue-2633.rs | 31 - src/test/run-pass/issues/issue-2642.rs | 10 - src/test/run-pass/issues/issue-26468.rs | 29 - src/test/run-pass/issues/issue-26484.rs | 11 - src/test/run-pass/issues/issue-26641.rs | 6 - src/test/run-pass/issues/issue-26655.rs | 25 - src/test/run-pass/issues/issue-26709.rs | 17 - src/test/run-pass/issues/issue-26802.rs | 14 - src/test/run-pass/issues/issue-26805.rs | 6 - src/test/run-pass/issues/issue-26873-multifile.rs | 11 - .../run-pass/issues/issue-26873-multifile/A/B.rs | 4 - .../run-pass/issues/issue-26873-multifile/A/C.rs | 6 - .../run-pass/issues/issue-26873-multifile/A/mod.rs | 5 - .../issue-26873-multifile/compiletest-ignore-dir | 0 .../run-pass/issues/issue-26873-multifile/mod.rs | 4 - src/test/run-pass/issues/issue-26873-onefile.rs | 25 - src/test/run-pass/issues/issue-26996.rs | 24 - src/test/run-pass/issues/issue-27021.rs | 28 - .../issues/issue-27054-primitive-binary-ops.rs | 5 - src/test/run-pass/issues/issue-2708.rs | 30 - src/test/run-pass/issues/issue-2718.rs | 327 -- src/test/run-pass/issues/issue-2723-b.rs | 11 - src/test/run-pass/issues/issue-27240.rs | 26 - src/test/run-pass/issues/issue-27268.rs | 4 - src/test/run-pass/issues/issue-27320.rs | 15 - src/test/run-pass/issues/issue-2734.rs | 24 - src/test/run-pass/issues/issue-2735-2.rs | 27 - src/test/run-pass/issues/issue-2735-3.rs | 27 - src/test/run-pass/issues/issue-2735.rs | 24 - .../run-pass/issues/issue-27401-dropflag-reinit.rs | 27 - src/test/run-pass/issues/issue-2748-b.rs | 11 - src/test/run-pass/issues/issue-27639.rs | 11 - src/test/run-pass/issues/issue-27859.rs | 21 - src/test/run-pass/issues/issue-27890.rs | 7 - src/test/run-pass/issues/issue-27901.rs | 11 - src/test/run-pass/issues/issue-27949.rs | 41 - src/test/run-pass/issues/issue-27997.rs | 37 - src/test/run-pass/issues/issue-28181.rs | 6 - .../run-pass/issues/issue-28498-must-work-ex1.rs | 18 - .../run-pass/issues/issue-28498-must-work-ex2.rs | 20 - src/test/run-pass/issues/issue-28498-ugeh-ex1.rs | 27 - .../issues/issue-28498-ugeh-with-lifetime-param.rs | 38 - .../issues/issue-28498-ugeh-with-passed-to-fn.rs | 46 - .../issues/issue-28498-ugeh-with-trait-bound.rs | 41 - src/test/run-pass/issues/issue-28550.rs | 16 - src/test/run-pass/issues/issue-28676.rs | 35 - src/test/run-pass/issues/issue-28777.rs | 21 - src/test/run-pass/issues/issue-28828.rs | 18 - src/test/run-pass/issues/issue-28839.rs | 15 - src/test/run-pass/issues/issue-2895.rs | 28 - src/test/run-pass/issues/issue-28950.rs | 22 - src/test/run-pass/issues/issue-28983.rs | 22 - src/test/run-pass/issues/issue-29053.rs | 12 - src/test/run-pass/issues/issue-29071-2.rs | 32 - src/test/run-pass/issues/issue-29092.rs | 26 - src/test/run-pass/issues/issue-29166.rs | 21 - src/test/run-pass/issues/issue-29227.rs | 142 - src/test/run-pass/issues/issue-2935.rs | 29 - src/test/run-pass/issues/issue-2936.rs | 31 - src/test/run-pass/issues/issue-29466.rs | 3603 -------------------- src/test/run-pass/issues/issue-29485.rs | 18 - src/test/run-pass/issues/issue-29488.rs | 23 - src/test/run-pass/issues/issue-29522.rs | 17 - src/test/run-pass/issues/issue-29663.rs | 56 - src/test/run-pass/issues/issue-29668.rs | 16 - src/test/run-pass/issues/issue-29746.rs | 36 - src/test/run-pass/issues/issue-29844.rs | 24 - src/test/run-pass/issues/issue-2989.rs | 36 - src/test/run-pass/issues/issue-29914-2.rs | 6 - src/test/run-pass/issues/issue-29914-3.rs | 7 - src/test/run-pass/issues/issue-29914.rs | 10 - src/test/run-pass/issues/issue-29927-1.rs | 11 - src/test/run-pass/issues/issue-29927.rs | 11 - src/test/run-pass/issues/issue-29948.rs | 40 - src/test/run-pass/issues/issue-30018-nopanic.rs | 103 - src/test/run-pass/issues/issue-30018-panic.rs | 25 - src/test/run-pass/issues/issue-30081.rs | 15 - src/test/run-pass/issues/issue-3012-2.rs | 13 - src/test/run-pass/issues/issue-3026.rs | 13 - src/test/run-pass/issues/issue-3037.rs | 16 - src/test/run-pass/issues/issue-30371.rs | 10 - src/test/run-pass/issues/issue-30490.rs | 102 - src/test/run-pass/issues/issue-3052.rs | 13 - src/test/run-pass/issues/issue-30530.rs | 28 - src/test/run-pass/issues/issue-30615.rs | 5 - src/test/run-pass/issues/issue-30756.rs | 7 - src/test/run-pass/issues/issue-30891.rs | 10 - src/test/run-pass/issues/issue-3091.rs | 7 - src/test/run-pass/issues/issue-3109.rs | 4 - src/test/run-pass/issues/issue-3121.rs | 25 - src/test/run-pass/issues/issue-31267-additional.rs | 20 - src/test/run-pass/issues/issue-31267.rs | 14 - src/test/run-pass/issues/issue-31299.rs | 34 - src/test/run-pass/issues/issue-3136-b.rs | 8 - src/test/run-pass/issues/issue-31702.rs | 10 - src/test/run-pass/issues/issue-31776.rs | 57 - src/test/run-pass/issues/issue-32008.rs | 28 - src/test/run-pass/issues/issue-3211.rs | 7 - src/test/run-pass/issues/issue-3220.rs | 25 - src/test/run-pass/issues/issue-32292.rs | 9 - src/test/run-pass/issues/issue-32389.rs | 11 - src/test/run-pass/issues/issue-32518.rs | 13 - src/test/run-pass/issues/issue-32805.rs | 10 - src/test/run-pass/issues/issue-3290.rs | 8 - src/test/run-pass/issues/issue-32947.rs | 24 - src/test/run-pass/issues/issue-33096.rs | 18 - src/test/run-pass/issues/issue-33185.rs | 17 - src/test/run-pass/issues/issue-33187.rs | 18 - src/test/run-pass/issues/issue-33202.rs | 9 - src/test/run-pass/issues/issue-333.rs | 7 - src/test/run-pass/issues/issue-33387.rs | 32 - src/test/run-pass/issues/issue-33461.rs | 28 - src/test/run-pass/issues/issue-33498.rs | 11 - src/test/run-pass/issues/issue-33537.rs | 14 - src/test/run-pass/issues/issue-33687.rs | 17 - src/test/run-pass/issues/issue-33770.rs | 95 - src/test/run-pass/issues/issue-3389.rs | 26 - src/test/run-pass/issues/issue-33992.rs | 32 - src/test/run-pass/issues/issue-34053.rs | 30 - src/test/run-pass/issues/issue-34074.rs | 10 - src/test/run-pass/issues/issue-3429.rs | 8 - src/test/run-pass/issues/issue-34427.rs | 17 - src/test/run-pass/issues/issue-3447.rs | 33 - src/test/run-pass/issues/issue-34503.rs | 11 - src/test/run-pass/issues/issue-34569.rs | 17 - src/test/run-pass/issues/issue-34571.rs | 11 - src/test/run-pass/issues/issue-34784.rs | 19 - src/test/run-pass/issues/issue-34796.rs | 28 - src/test/run-pass/issues/issue-34798.rs | 25 - src/test/run-pass/issues/issue-34932.rs | 12 - src/test/run-pass/issues/issue-3500.rs | 10 - src/test/run-pass/issues/issue-35423.rs | 9 - src/test/run-pass/issues/issue-3556.rs | 36 - src/test/run-pass/issues/issue-3559.rs | 18 - src/test/run-pass/issues/issue-35600.rs | 16 - src/test/run-pass/issues/issue-3563-3.rs | 180 - src/test/run-pass/issues/issue-3574.rs | 14 - src/test/run-pass/issues/issue-35815.rs | 15 - src/test/run-pass/issues/issue-36023.rs | 24 - .../issues/issue-36036-associated-type-layout.rs | 27 - src/test/run-pass/issues/issue-36053.rs | 22 - .../issues/issue-36139-normalize-closure-sig.rs | 19 - src/test/run-pass/issues/issue-36260.rs | 13 - .../run-pass/issues/issue-36278-prefix-nesting.rs | 19 - src/test/run-pass/issues/issue-36381.rs | 25 - src/test/run-pass/issues/issue-36401.rs | 16 - src/test/run-pass/issues/issue-36474.rs | 31 - src/test/run-pass/issues/issue-3656.rs | 30 - .../issues/issue-36744-bitcast-args-if-needed.rs | 23 - src/test/run-pass/issues/issue-36768.rs | 9 - .../run-pass/issues/issue-36786-resolve-call.rs | 8 - src/test/run-pass/issues/issue-36792.rs | 7 - src/test/run-pass/issues/issue-36816.rs | 7 - src/test/run-pass/issues/issue-3683.rs | 18 - src/test/run-pass/issues/issue-36856.rs | 15 - src/test/run-pass/issues/issue-36936.rs | 26 - src/test/run-pass/issues/issue-36954.rs | 8 - src/test/run-pass/issues/issue-3702.rs | 13 - src/test/run-pass/issues/issue-37109.rs | 16 - src/test/run-pass/issues/issue-37175.rs | 5 - src/test/run-pass/issues/issue-37222.rs | 17 - .../run-pass/issues/issue-37291/auxiliary/lib.rs | 42 - src/test/run-pass/issues/issue-37291/main.rs | 21 - src/test/run-pass/issues/issue-3743.rs | 55 - src/test/run-pass/issues/issue-3753.rs | 32 - src/test/run-pass/issues/issue-37686.rs | 7 - src/test/run-pass/issues/issue-3794.rs | 32 - src/test/run-pass/issues/issue-37991.rs | 17 - src/test/run-pass/issues/issue-38002.rs | 35 - src/test/run-pass/issues/issue-38033.rs | 79 - src/test/run-pass/issues/issue-38074.rs | 20 - src/test/run-pass/issues/issue-38091.rs | 20 - src/test/run-pass/issues/issue-38190.rs | 15 - src/test/run-pass/issues/issue-38226.rs | 15 - src/test/run-pass/issues/issue-38437.rs | 46 - src/test/run-pass/issues/issue-3847.rs | 13 - src/test/run-pass/issues/issue-38556.rs | 13 - src/test/run-pass/issues/issue-38763.rs | 12 - src/test/run-pass/issues/issue-3878.rs | 10 - src/test/run-pass/issues/issue-38942.rs | 17 - src/test/run-pass/issues/issue-3895.rs | 11 - src/test/run-pass/issues/issue-38987.rs | 4 - src/test/run-pass/issues/issue-3904.rs | 25 - src/test/run-pass/issues/issue-39292.rs | 17 - src/test/run-pass/issues/issue-3935.rs | 13 - src/test/run-pass/issues/issue-39367.rs | 39 - src/test/run-pass/issues/issue-39548.rs | 6 - src/test/run-pass/issues/issue-39709.rs | 5 - src/test/run-pass/issues/issue-39720.rs | 26 - src/test/run-pass/issues/issue-39720.stderr | 16 - src/test/run-pass/issues/issue-3979-generics.rs | 36 - src/test/run-pass/issues/issue-3979-xcrate.rs | 25 - src/test/run-pass/issues/issue-3979.rs | 34 - src/test/run-pass/issues/issue-39808.rs | 17 - src/test/run-pass/issues/issue-39823.rs | 25 - src/test/run-pass/issues/issue-39827.rs | 34 - src/test/run-pass/issues/issue-40003.rs | 178 - src/test/run-pass/issues/issue-40085.rs | 13 - src/test/run-pass/issues/issue-40235.rs | 8 - src/test/run-pass/issues/issue-40408.rs | 7 - src/test/run-pass/issues/issue-40469.rs | 9 - src/test/run-pass/issues/issue-40770.rs | 11 - src/test/run-pass/issues/issue-40847.rs | 17 - src/test/run-pass/issues/issue-40883.rs | 93 - src/test/run-pass/issues/issue-40951.rs | 12 - src/test/run-pass/issues/issue-41053.rs | 21 - src/test/run-pass/issues/issue-4107.rs | 26 - src/test/run-pass/issues/issue-41213.rs | 24 - src/test/run-pass/issues/issue-41479.rs | 9 - src/test/run-pass/issues/issue-41498.rs | 17 - src/test/run-pass/issues/issue-41604.rs | 11 - src/test/run-pass/issues/issue-41677.rs | 28 - src/test/run-pass/issues/issue-41696.rs | 54 - src/test/run-pass/issues/issue-41744.rs | 7 - src/test/run-pass/issues/issue-41803.rs | 21 - .../run-pass/issues/issue-41849-variance-req.rs | 35 - src/test/run-pass/issues/issue-41888.rs | 34 - src/test/run-pass/issues/issue-42007.rs | 11 - src/test/run-pass/issues/issue-4208.rs | 12 - src/test/run-pass/issues/issue-42148.rs | 6 - src/test/run-pass/issues/issue-42210.rs | 20 - src/test/run-pass/issues/issue-4228.rs | 16 - src/test/run-pass/issues/issue-42453.rs | 10 - src/test/run-pass/issues/issue-42463.rs | 32 - src/test/run-pass/issues/issue-4252.rs | 33 - src/test/run-pass/issues/issue-42552.rs | 31 - src/test/run-pass/issues/issue-42679.rs | 22 - src/test/run-pass/issues/issue-42747.rs | 46 - src/test/run-pass/issues/issue-43132.rs | 65 - src/test/run-pass/issues/issue-43205.rs | 5 - src/test/run-pass/issues/issue-43291.rs | 9 - src/test/run-pass/issues/issue-4333.rs | 10 - src/test/run-pass/issues/issue-43692.rs | 5 - src/test/run-pass/issues/issue-43853.rs | 17 - src/test/run-pass/issues/issue-4387.rs | 6 - src/test/run-pass/issues/issue-43910.rs | 7 - src/test/run-pass/issues/issue-43923.rs | 12 - src/test/run-pass/issues/issue-4401.rs | 7 - src/test/run-pass/issues/issue-44333.rs | 20 - src/test/run-pass/issues/issue-4446.rs | 15 - src/test/run-pass/issues/issue-4448.rs | 16 - src/test/run-pass/issues/issue-45124.rs | 18 - src/test/run-pass/issues/issue-45152.rs | 24 - src/test/run-pass/issues/issue-4541.rs | 23 - src/test/run-pass/issues/issue-4542.rs | 13 - src/test/run-pass/issues/issue-4545.rs | 7 - src/test/run-pass/issues/issue-45510.rs | 32 - src/test/run-pass/issues/issue-45731.rs | 26 - src/test/run-pass/issues/issue-46069.rs | 23 - src/test/run-pass/issues/issue-46095.rs | 30 - src/test/run-pass/issues/issue-46519.rs | 28 - src/test/run-pass/issues/issue-46553.rs | 23 - src/test/run-pass/issues/issue-46845.rs | 32 - src/test/run-pass/issues/issue-46855.rs | 24 - .../issues/issue-46920-byte-array-patterns.rs | 28 - src/test/run-pass/issues/issue-47139-1.rs | 78 - src/test/run-pass/issues/issue-47139-2.rs | 66 - src/test/run-pass/issues/issue-4734.rs | 37 - src/test/run-pass/issues/issue-4735.rs | 19 - src/test/run-pass/issues/issue-47364.rs | 59 - src/test/run-pass/issues/issue-4759-1.rs | 4 - src/test/run-pass/issues/issue-4759.rs | 20 - src/test/run-pass/issues/issue-47638.rs | 10 - src/test/run-pass/issues/issue-48006.rs | 15 - src/test/run-pass/issues/issue-48159.rs | 27 - src/test/run-pass/issues/issue-48508-aux.rs | 7 - src/test/run-pass/issues/issue-48508.rs | 19 - src/test/run-pass/issues/issue-4865-1.rs | 33 - src/test/run-pass/issues/issue-4865-2.rs | 24 - src/test/run-pass/issues/issue-4865-3.rs | 17 - src/test/run-pass/issues/issue-4875.rs | 15 - src/test/run-pass/issues/issue-48962.rs | 34 - src/test/run-pass/issues/issue-48984.rs | 9 - src/test/run-pass/issues/issue-49298.rs | 42 - ...on-shorthand-field-patterns-in-pattern-macro.rs | 16 - src/test/run-pass/issues/issue-49632.rs | 8 - src/test/run-pass/issues/issue-49685.rs | 13 - src/test/run-pass/issues/issue-49854.rs | 9 - src/test/run-pass/issues/issue-49955-2.rs | 19 - src/test/run-pass/issues/issue-49955.rs | 20 - src/test/run-pass/issues/issue-49973.rs | 11 - .../issue-5008-borrowed-traitobject-method-call.rs | 34 - src/test/run-pass/issues/issue-50415.rs | 18 - src/test/run-pass/issues/issue-50442.rs | 13 - src/test/run-pass/issues/issue-5060.rs | 16 - src/test/run-pass/issues/issue-50689.rs | 9 - src/test/run-pass/issues/issue-50731.rs | 6 - src/test/run-pass/issues/issue-50811.rs | 56 - .../auxiliary/lib.rs | 14 - .../issues/issue-50865-private-impl-trait/main.rs | 16 - src/test/run-pass/issues/issue-51185.rs | 8 - src/test/run-pass/issues/issue-51345.rs | 8 - src/test/run-pass/issues/issue-51582.rs | 18 - src/test/run-pass/issues/issue-51907.rs | 17 - src/test/run-pass/issues/issue-5192.rs | 41 - .../issues/issue-52140/auxiliary/some_crate.rs | 5 - src/test/run-pass/issues/issue-52140/main.rs | 13 - .../issues/issue-52141/auxiliary/some_crate.rs | 5 - src/test/run-pass/issues/issue-52141/main.rs | 16 - src/test/run-pass/issues/issue-52169.rs | 14 - src/test/run-pass/issues/issue-5239-2.rs | 9 - src/test/run-pass/issues/issue-5243.rs | 17 - src/test/run-pass/issues/issue-52557.rs | 30 - .../run-pass/issues/issue-52705/auxiliary/png2.rs | 3 - src/test/run-pass/issues/issue-52705/main.rs | 15 - src/test/run-pass/issues/issue-5280.rs | 18 - src/test/run-pass/issues/issue-5315.rs | 9 - .../issues/issue-5321-immediates-with-bare-self.rs | 15 - src/test/run-pass/issues/issue-53333.rs | 9 - src/test/run-pass/issues/issue-53728.rs | 19 - src/test/run-pass/issues/issue-53843.rs | 26 - .../issue-54462-mutable-noalias-correctness.rs | 25 - src/test/run-pass/issues/issue-54467.rs | 46 - src/test/run-pass/issues/issue-54477-reduced-2.rs | 26 - src/test/run-pass/issues/issue-54696.rs | 8 - src/test/run-pass/issues/issue-5518.rs | 8 - src/test/run-pass/issues/issue-5521.rs | 17 - src/test/run-pass/issues/issue-5530.rs | 40 - src/test/run-pass/issues/issue-55376.rs | 16 - src/test/run-pass/issues/issue-55380.rs | 28 - src/test/run-pass/issues/issue-5550.rs | 9 - src/test/run-pass/issues/issue-5554.rs | 29 - src/test/run-pass/issues/issue-56237.rs | 13 - src/test/run-pass/issues/issue-5666.rs | 27 - src/test/run-pass/issues/issue-5688.rs | 20 - src/test/run-pass/issues/issue-5708.rs | 55 - src/test/run-pass/issues/issue-5718.rs | 26 - src/test/run-pass/issues/issue-5741.rs | 9 - src/test/run-pass/issues/issue-5791.rs | 12 - src/test/run-pass/issues/issue-58212.rs | 16 - .../issues/issue-58435-ice-with-assoc-const.rs | 18 - src/test/run-pass/issues/issue-58463.rs | 8 - src/test/run-pass/issues/issue-5917.rs | 9 - src/test/run-pass/issues/issue-5988.rs | 24 - src/test/run-pass/issues/issue-5997.rs | 15 - src/test/run-pass/issues/issue-6117.rs | 12 - src/test/run-pass/issues/issue-6128.rs | 24 - src/test/run-pass/issues/issue-6130.rs | 10 - src/test/run-pass/issues/issue-6153.rs | 13 - src/test/run-pass/issues/issue-6157.rs | 23 - src/test/run-pass/issues/issue-61696.rs | 66 - src/test/run-pass/issues/issue-61894.rs | 21 - src/test/run-pass/issues/issue-6318.rs | 22 - src/test/run-pass/issues/issue-6334.rs | 46 - src/test/run-pass/issues/issue-6344-let.rs | 15 - src/test/run-pass/issues/issue-6344-match.rs | 18 - src/test/run-pass/issues/issue-6449.rs | 44 - src/test/run-pass/issues/issue-6892.rs | 58 - src/test/run-pass/issues/issue-6919.rs | 12 - src/test/run-pass/issues/issue-7012.rs | 22 - src/test/run-pass/issues/issue-7178.rs | 10 - src/test/run-pass/issues/issue-7222.rs | 12 - src/test/run-pass/issues/issue-7344.rs | 22 - .../issues/issue-7519-match-unit-in-arg.rs | 12 - src/test/run-pass/issues/issue-7563.rs | 28 - src/test/run-pass/issues/issue-7575.rs | 17 - src/test/run-pass/issues/issue-7660.rs | 18 - src/test/run-pass/issues/issue-7663.rs | 32 - src/test/run-pass/issues/issue-7784.rs | 31 - src/test/run-pass/issues/issue-7899.rs | 11 - src/test/run-pass/issues/issue-7911.rs | 37 - src/test/run-pass/issues/issue-8044.rs | 11 - src/test/run-pass/issues/issue-8248.rs | 15 - src/test/run-pass/issues/issue-8249.rs | 20 - src/test/run-pass/issues/issue-8259.rs | 12 - src/test/run-pass/issues/issue-8351-1.rs | 16 - src/test/run-pass/issues/issue-8351-2.rs | 16 - src/test/run-pass/issues/issue-8391.rs | 9 - src/test/run-pass/issues/issue-8401.rs | 8 - src/test/run-pass/issues/issue-8460.rs | 51 - src/test/run-pass/issues/issue-8498.rs | 27 - src/test/run-pass/issues/issue-8506.rs | 14 - src/test/run-pass/issues/issue-868.rs | 18 - src/test/run-pass/issues/issue-8709.rs | 14 - src/test/run-pass/issues/issue-8783.rs | 24 - src/test/run-pass/issues/issue-8827.rs | 53 - src/test/run-pass/issues/issue-8851.rs | 30 - src/test/run-pass/issues/issue-8860.rs | 49 - src/test/run-pass/issues/issue-8898.rs | 18 - src/test/run-pass/issues/issue-9047.rs | 14 - src/test/run-pass/issues/issue-9123.rs | 8 - src/test/run-pass/issues/issue-9129.rs | 35 - src/test/run-pass/issues/issue-9155.rs | 12 - src/test/run-pass/issues/issue-9188.rs | 11 - src/test/run-pass/issues/issue-9259.rs | 16 - src/test/run-pass/issues/issue-9382.rs | 41 - .../issues/issue-9394-inherited-trait-calls.rs | 62 - src/test/run-pass/issues/issue-9396.rs | 24 - src/test/run-pass/issues/issue-9446.rs | 30 - src/test/run-pass/issues/issue-9737.rs | 10 - src/test/run-pass/issues/issue-979.rs | 29 - src/test/run-pass/issues/issue-9837.rs | 11 - src/test/run-pass/issues/issue-9906.rs | 11 - src/test/run-pass/issues/issue-9918.rs | 5 - src/test/run-pass/issues/issue-9942.rs | 6 - src/test/run-pass/issues/issue-9951.rs | 21 - src/test/run-pass/issues/issue-9968.rs | 13 - src/test/run-pass/istr.rs | 53 - src/test/run-pass/item-name-overload.rs | 17 - .../into-iterator-type-inference-shift.rs | 36 - .../iterators/iter-cloned-type-inference.rs | 16 - src/test/run-pass/iterators/iter-range.rs | 14 - .../run-pass/iterators/iter-step-overflow-debug.rs | 21 - .../iterators/iter-step-overflow-ndebug.rs | 12 - .../run-pass/iterators/iter-sum-overflow-debug.rs | 27 - .../run-pass/iterators/iter-sum-overflow-ndebug.rs | 14 - .../iterators/iter-sum-overflow-overflow-checks.rs | 27 - src/test/run-pass/iterators/iter-zip.rs | 103 - src/test/run-pass/keyword-changes-2012-07-31.rs | 20 - .../run-pass/kindck-implicit-close-over-mut-var.rs | 49 - src/test/run-pass/kinds-in-metadata.rs | 17 - src/test/run-pass/lambda-infer-unresolved.rs | 15 - src/test/run-pass/lambda-var-hygiene.rs | 12 - src/test/run-pass/large-records.rs | 38 - src/test/run-pass/last-use-in-block.rs | 21 - src/test/run-pass/last-use-in-cap-clause.rs | 17 - src/test/run-pass/last-use-is-capture.rs | 15 - src/test/run-pass/lazy-and-or.rs | 12 - src/test/run-pass/lazy-init.rs | 8 - src/test/run-pass/leak-unique-as-tydesc.rs | 8 - src/test/run-pass/lex-bare-cr-nondoc-comment.rs | 9 - ...crlf-line-endings-string-literal-doc-comment.rs | 41 - src/test/run-pass/lexical-scoping.rs | 19 - src/test/run-pass/lib-defaults.rs | 17 - src/test/run-pass/link-cfg-works.rs | 13 - src/test/run-pass/link-section.rs | 37 - src/test/run-pass/linkage1.rs | 32 - src/test/run-pass/lint-cap.rs | 8 - .../run-pass/lint-dead-code-associated-type.rs | 19 - src/test/run-pass/lint-dead-code-variant.rs | 14 - .../lint-expr-stmt-attrs-for-early-lints.rs | 14 - .../run-pass/lint-unknown-lints-at-crate-level.rs | 7 - src/test/run-pass/list.rs | 10 - .../liveness-assign-imm-local-after-ret.rs | 16 - src/test/run-pass/llvm-pr32379.rs | 14 - src/test/run-pass/log-err-phi.rs | 7 - .../log-knows-the-names-of-variants-in-std.rs | 27 - .../run-pass/log-knows-the-names-of-variants.rs | 21 - src/test/run-pass/log-poly.rs | 13 - src/test/run-pass/logging-only-prints-once.rs | 28 - src/test/run-pass/logging_before_rt_started.rs | 12 - src/test/run-pass/long-while.rs | 12 - src/test/run-pass/lto-many-codegen-units.rs | 6 - src/test/run-pass/lto-still-runs-thread-dtors.rs | 32 - .../run-pass/lub-glb-with-unbound-infer-var.rs | 15 - src/test/run-pass/macro-quote-cond.rs | 48 - src/test/run-pass/macro-quote-test.rs | 12 - .../run-pass/macros/assert-eq-macro-success.rs | 13 - .../run-pass/macros/assert-eq-macro-unsized.rs | 4 - .../run-pass/macros/assert-ne-macro-success.rs | 13 - .../run-pass/macros/assert-ne-macro-unsized.rs | 4 - .../macros/auxiliary/macro-comma-support.rs | 1 - .../macros/auxiliary/macro-include-items-expr.rs | 3 - .../macros/auxiliary/macro-include-items-item.rs | 3 - .../macros/auxiliary/macro_crate_def_only.rs | 4 - .../macros/auxiliary/macro_export_inner_module.rs | 6 - .../macros/auxiliary/macro_with_super_1.rs | 16 - src/test/run-pass/macros/auxiliary/two_macros.rs | 5 - .../run-pass/macros/auxiliary/use-macro-self.rs | 6 - src/test/run-pass/macros/colorful-write-macros.rs | 34 - .../run-pass/macros/conditional-debug-macro-on.rs | 8 - src/test/run-pass/macros/die-macro.rs | 16 - src/test/run-pass/macros/issue-25274.rs | 18 - .../log_syntax-trace_macros-macro-locations.rs | 22 - .../log_syntax-trace_macros-macro-locations.stdout | 3 - src/test/run-pass/macros/macro-2.rs | 12 - src/test/run-pass/macros/macro-as-fn-body.rs | 33 - .../run-pass/macros/macro-attribute-expansion.rs | 16 - src/test/run-pass/macros/macro-attributes.rs | 23 - .../run-pass/macros/macro-block-nonterminal.rs | 11 - src/test/run-pass/macros/macro-crate-def-only.rs | 10 - .../macros/macro-crate-nonterminal-renamed.rs | 10 - .../run-pass/macros/macro-crate-nonterminal.rs | 10 - src/test/run-pass/macros/macro-crate-use.rs | 17 - src/test/run-pass/macros/macro-deep_expansion.rs | 17 - .../macros/macro-delimiter-significance.rs | 4 - src/test/run-pass/macros/macro-doc-comments.rs | 26 - src/test/run-pass/macros/macro-doc-escapes.rs | 16 - .../run-pass/macros/macro-doc-raw-str-hashes.rs | 30 - .../run-pass/macros/macro-export-inner-module.rs | 9 - src/test/run-pass/macros/macro-first-set.rs | 277 -- src/test/run-pass/macros/macro-followed-by-seq.rs | 14 - src/test/run-pass/macros/macro-include-items.rs | 13 - src/test/run-pass/macros/macro-interpolation.rs | 21 - ...ro-invocation-in-count-expr-fixed-array-type.rs | 10 - .../macros/macro-lifetime-used-with-bound.rs | 15 - .../macros/macro-lifetime-used-with-labels.rs | 36 - .../macros/macro-lifetime-used-with-labels.stderr | 11 - .../macros/macro-lifetime-used-with-static.rs | 14 - src/test/run-pass/macros/macro-lifetime.rs | 14 - src/test/run-pass/macros/macro-literal.rs | 133 - src/test/run-pass/macros/macro-meta-items.rs | 31 - .../run-pass/macros/macro-method-issue-4621.rs | 10 - src/test/run-pass/macros/macro-multiple-items.rs | 16 - src/test/run-pass/macros/macro-named-default.rs | 18 - .../macros/macro-nested_definition_issue-31946.rs | 9 - src/test/run-pass/macros/macro-nested_expr.rs | 22 - .../run-pass/macros/macro-nested_stmt_macros.rs | 23 - src/test/run-pass/macros/macro-nt-list.rs | 21 - src/test/run-pass/macros/macro-of-higher-order.rs | 22 - src/test/run-pass/macros/macro-pat-follow.rs | 31 - src/test/run-pass/macros/macro-pat-neg-lit.rs | 25 - src/test/run-pass/macros/macro-pat.rs | 65 - src/test/run-pass/macros/macro-path.rs | 18 - src/test/run-pass/macros/macro-pub-matcher.rs | 118 - .../run-pass/macros/macro-seq-followed-by-seq.rs | 17 - src/test/run-pass/macros/macro-stmt.rs | 31 - .../macros/macro-stmt_macro_in_expr_macro.rs | 21 - .../run-pass/macros/macro-tt-followed-by-seq.rs | 27 - src/test/run-pass/macros/macro-use-all-and-none.rs | 11 - .../run-pass/macros/macro-use-all-and-none.stderr | 8 - src/test/run-pass/macros/macro-use-all.rs | 10 - src/test/run-pass/macros/macro-use-both.rs | 10 - src/test/run-pass/macros/macro-use-one.rs | 9 - src/test/run-pass/macros/macro-with-attrs1.rs | 13 - src/test/run-pass/macros/macro-with-attrs2.rs | 11 - .../macros/macro-with-braces-in-expr-position.rs | 22 - src/test/run-pass/macros/macro_with_super_2.rs | 13 - src/test/run-pass/macros/meta-variable-misuse.rs | 34 - .../macros/parse-complex-macro-invoc-op.rs | 42 - .../run-pass/macros/paths-in-macro-invocations.rs | 36 - src/test/run-pass/macros/pub-item-inside-macro.rs | 18 - .../run-pass/macros/pub-method-inside-macro.rs | 22 - src/test/run-pass/macros/semi-after-macro-ty.rs | 8 - .../run-pass/macros/stmt_expr_attr_macro_parse.rs | 23 - src/test/run-pass/macros/syntax-extension-cfg.rs | 24 - .../includeme.fragment | 7 - .../macros/syntax-extension-source-utils.rs | 37 - src/test/run-pass/macros/try-macro.rs | 48 - src/test/run-pass/macros/two-macro-use.rs | 11 - src/test/run-pass/macros/type-macros-hlist.rs | 78 - src/test/run-pass/macros/type-macros-simple.rs | 30 - .../macros/typeck-macro-interaction-issue-8852.rs | 30 - src/test/run-pass/macros/use-macro-self.rs | 12 - src/test/run-pass/max-min-classes.rs | 32 - .../run-pass/methods/auxiliary/method_self_arg1.rs | 37 - .../run-pass/methods/auxiliary/method_self_arg2.rs | 54 - .../method-argument-inference-associated-type.rs | 28 - .../method-early-bound-lifetimes-on-self.rs | 31 - .../method-mut-self-modifies-mut-slice-lvalue.rs | 44 - .../methods/method-normalize-bounds-issue-20604.rs | 61 - .../methods/method-probe-no-guessing-dyn-trait.rs | 60 - src/test/run-pass/methods/method-projection.rs | 70 - .../methods/method-recursive-blanket-impl.rs | 41 - src/test/run-pass/methods/method-self-arg-aux1.rs | 20 - src/test/run-pass/methods/method-self-arg-aux2.rs | 24 - src/test/run-pass/methods/method-self-arg-trait.rs | 69 - src/test/run-pass/methods/method-self-arg.rs | 48 - .../methods/method-two-trait-defer-resolution-1.rs | 37 - .../methods/method-two-trait-defer-resolution-2.rs | 48 - ...od-two-traits-distinguished-via-where-clause.rs | 27 - src/test/run-pass/methods/method-where-clause.rs | 34 - src/test/run-pass/mid-path-type-params.rs | 37 - src/test/run-pass/minmax-stability-issue-23687.rs | 64 - .../run-pass/mir/auxiliary/mir_external_refs.rs | 17 - .../run-pass/mir/mir-inlining/ice-issue-45493.rs | 17 - .../run-pass/mir/mir-inlining/ice-issue-45885.rs | 29 - .../mir-inlining/no-trait-method-issue-40473.rs | 16 - .../run-pass/mir/mir-typeck-normalize-fn-sig.rs | 30 - src/test/run-pass/mir/mir_adt_construction.rs | 92 - src/test/run-pass/mir/mir_ascription_coercion.rs | 10 - src/test/run-pass/mir/mir_augmented_assignments.rs | 160 - src/test/run-pass/mir/mir_autoderef.rs | 28 - src/test/run-pass/mir/mir_boxing.rs | 10 - .../run-pass/mir/mir_build_match_comparisons.rs | 59 - .../run-pass/mir/mir_call_with_associated_type.rs | 16 - src/test/run-pass/mir/mir_calls_to_shims.rs | 49 - src/test/run-pass/mir/mir_cast_fn_ret.rs | 21 - src/test/run-pass/mir/mir_codegen_array.rs | 11 - src/test/run-pass/mir/mir_codegen_array_2.rs | 9 - .../run-pass/mir/mir_codegen_call_converging.rs | 17 - src/test/run-pass/mir/mir_codegen_calls.rs | 191 -- .../run-pass/mir/mir_codegen_calls_variadic.rs | 22 - src/test/run-pass/mir/mir_codegen_critical_edge.rs | 44 - src/test/run-pass/mir/mir_codegen_spike1.rs | 12 - src/test/run-pass/mir/mir_codegen_switch.rs | 35 - src/test/run-pass/mir/mir_codegen_switchint.rs | 12 - src/test/run-pass/mir/mir_coercion_casts.rs | 10 - src/test/run-pass/mir/mir_coercions.rs | 71 - src/test/run-pass/mir/mir_constval_adts.rs | 34 - src/test/run-pass/mir/mir_drop_order.rs | 48 - src/test/run-pass/mir/mir_early_return_scope.rs | 29 - src/test/run-pass/mir/mir_fat_ptr.rs | 52 - src/test/run-pass/mir/mir_fat_ptr_drop.rs | 32 - src/test/run-pass/mir/mir_heavy_promoted.rs | 11 - src/test/run-pass/mir/mir_match_arm_guard.rs | 16 - src/test/run-pass/mir/mir_match_test.rs | 83 - src/test/run-pass/mir/mir_misc_casts.rs | 320 -- src/test/run-pass/mir/mir_overflow_off.rs | 17 - src/test/run-pass/mir/mir_raw_fat_ptr.rs | 158 - src/test/run-pass/mir/mir_refs_correct.rs | 209 -- src/test/run-pass/mir/mir_small_agg_arg.rs | 8 - src/test/run-pass/mir/mir_static_subtype.rs | 9 - src/test/run-pass/mir/mir_struct_with_assoc_ty.rs | 29 - src/test/run-pass/mir/mir_temp_promotions.rs | 10 - src/test/run-pass/mir/mir_void_return.rs | 12 - src/test/run-pass/mir/mir_void_return_2.rs | 10 - .../run-pass/modules/auxiliary/two_macros_2.rs | 3 - src/test/run-pass/modules/mod-inside-fn.rs | 13 - src/test/run-pass/modules/mod-view-items.rs | 14 - src/test/run-pass/modules/mod_dir_implicit.rs | 8 - .../mod_dir_implicit_aux/compiletest-ignore-dir | 0 .../run-pass/modules/mod_dir_implicit_aux/mod.rs | 2 - src/test/run-pass/modules/mod_dir_path.rs | 23 - src/test/run-pass/modules/mod_dir_path2.rs | 12 - src/test/run-pass/modules/mod_dir_path3.rs | 11 - src/test/run-pass/modules/mod_dir_path_multi.rs | 17 - src/test/run-pass/modules/mod_dir_recursive.rs | 14 - src/test/run-pass/modules/mod_dir_simple.rs | 10 - .../modules/mod_dir_simple/compiletest-ignore-dir | 0 .../modules/mod_dir_simple/load_another_mod.rs | 3 - src/test/run-pass/modules/mod_dir_simple/test.rs | 2 - src/test/run-pass/modules/mod_file.rs | 10 - src/test/run-pass/modules/mod_file_aux.rs | 4 - .../run-pass/modules/mod_file_with_path_attr.rs | 11 - .../compiletest-ignore-dir | 0 .../float-template/inst_f32.rs | 3 - .../float-template/inst_f64.rs | 3 - .../float-template/inst_float.rs | 3 - src/test/run-pass/monad.rs | 48 - src/test/run-pass/monomorphize-abi-alignment.rs | 34 - .../monomorphized-callees-with-ty-params-3314.rs | 32 - src/test/run-pass/moves/move-1-unique.rs | 25 - src/test/run-pass/moves/move-2-unique.rs | 11 - src/test/run-pass/moves/move-2.rs | 7 - src/test/run-pass/moves/move-3-unique.rs | 25 - src/test/run-pass/moves/move-4-unique.rs | 19 - src/test/run-pass/moves/move-4.rs | 19 - src/test/run-pass/moves/move-arg-2-unique.rs | 13 - src/test/run-pass/moves/move-arg-2.rs | 13 - src/test/run-pass/moves/move-arg.rs | 5 - src/test/run-pass/moves/move-nullary-fn.rs | 13 - src/test/run-pass/moves/move-out-of-field.rs | 27 - src/test/run-pass/moves/move-scalar.rs | 10 - .../moves/moves-based-on-type-capture-clause.rs | 12 - src/test/run-pass/mpsc_stress.rs | 164 - src/test/run-pass/msvc-data-only.rs | 8 - src/test/run-pass/multi-panic.rs | 38 - src/test/run-pass/multibyte.rs | 7 - ...ultidispatch-conditional-impl-not-considered.rs | 24 - src/test/run-pass/multidispatch1.rs | 33 - src/test/run-pass/multidispatch2.rs | 39 - src/test/run-pass/multiline-comment.rs | 7 - src/test/run-pass/multiple-reprs.rs | 82 - src/test/run-pass/mut-function-arguments.rs | 21 - src/test/run-pass/mut-vstore-expr.rs | 6 - src/test/run-pass/mutual-recursion-group.rs | 16 - src/test/run-pass/native-print-no-runtime.rs | 9 - src/test/run-pass/negative.rs | 8 - src/test/run-pass/nested-block-comment.rs | 12 - src/test/run-pass/nested-class.rs | 25 - .../run-pass/nested-function-names-issue-8587.rs | 42 - src/test/run-pass/nested_item_main.rs | 10 - src/test/run-pass/never-result.rs | 20 - src/test/run-pass/never-type-rvalues.rs | 38 - src/test/run-pass/never_coercions.rs | 12 - src/test/run-pass/new-box-syntax.rs | 28 - src/test/run-pass/new-box.rs | 32 - src/test/run-pass/new-impl-syntax.rs | 29 - src/test/run-pass/new-import-syntax.rs | 5 - src/test/run-pass/new-style-constants.rs | 7 - src/test/run-pass/new-unicode-escapes.rs | 14 - src/test/run-pass/new-unsafe-pointers.rs | 7 - src/test/run-pass/newlambdas-ret-infer.rs | 12 - src/test/run-pass/newlambdas-ret-infer2.rs | 12 - src/test/run-pass/newlambdas.rs | 14 - src/test/run-pass/newtype-polymorphic.rs | 27 - src/test/run-pass/newtype-temporary.rs | 12 - src/test/run-pass/newtype.rs | 23 - src/test/run-pass/nil-decl-in-foreign.rs | 14 - src/test/run-pass/nll/issue-47153-generic-const.rs | 18 - src/test/run-pass/nll/issue-47589.rs | 23 - src/test/run-pass/nll/issue-48623-closure.rs | 16 - src/test/run-pass/nll/issue-48623-generator.rs | 18 - src/test/run-pass/nll/issue-50343.rs | 8 - .../nll/issue-50461-used-mut-from-moves.rs | 16 - .../run-pass/nll/issue-53123-raw-pointer-cast.rs | 26 - src/test/run-pass/nll/mutating_references.rs | 24 - src/test/run-pass/nll/process_or_insert_default.rs | 27 - src/test/run-pass/nll/rc-loop.rs | 28 - src/test/run-pass/no-core-1.rs | 15 - src/test/run-pass/no-core-2.rs | 20 - src/test/run-pass/no-landing-pads.rs | 23 - src/test/run-pass/no-std-1.rs | 10 - src/test/run-pass/no-std-2.rs | 10 - src/test/run-pass/no-std-3.rs | 17 - src/test/run-pass/no-stdio.rs | 120 - src/test/run-pass/non-built-in-quote.rs | 8 - src/test/run-pass/non-legacy-modes.rs | 22 - src/test/run-pass/non_modrs_mods/foors_mod.rs | 10 - .../foors_mod/compiletest-ignore-dir | 0 .../non_modrs_mods/foors_mod/inline/somename.rs | 3 - .../non_modrs_mods/foors_mod/inner_foors_mod.rs | 3 - .../foors_mod/inner_foors_mod/innest.rs | 3 - .../foors_mod/inner_modrs_mod/innest.rs | 3 - .../foors_mod/inner_modrs_mod/mod.rs | 3 - .../modrs_mod/compiletest-ignore-dir | 0 .../non_modrs_mods/modrs_mod/inline/somename.rs | 3 - .../non_modrs_mods/modrs_mod/inner_foors_mod.rs | 3 - .../modrs_mod/inner_foors_mod/innest.rs | 3 - .../modrs_mod/inner_modrs_mod/innest.rs | 3 - .../modrs_mod/inner_modrs_mod/mod.rs | 3 - src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs | 8 - src/test/run-pass/non_modrs_mods/non_modrs_mods.rs | 16 - .../some_crazy_attr_mod_dir/arbitrary_name.rs | 3 - .../some_crazy_attr_mod_dir/compiletest-ignore-dir | 0 .../inner_modrs_mod/innest.rs | 3 - .../some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs | 3 - src/test/run-pass/nul-characters.rs | 36 - src/test/run-pass/nullable-pointer-ffi-compat.rs | 28 - .../run-pass/nullable-pointer-iotareduction.rs | 73 - src/test/run-pass/nullable-pointer-size.rs | 35 - src/test/run-pass/numbers-arithmetic/arith-0.rs | 8 - src/test/run-pass/numbers-arithmetic/arith-1.rs | 24 - src/test/run-pass/numbers-arithmetic/arith-2.rs | 9 - .../run-pass/numbers-arithmetic/arith-unsigned.rs | 26 - src/test/run-pass/numbers-arithmetic/div-mod.rs | 19 - .../float-int-invalid-const-cast.rs | 53 - .../numbers-arithmetic/float-literal-inference.rs | 13 - src/test/run-pass/numbers-arithmetic/float-nan.rs | 83 - .../run-pass/numbers-arithmetic/float-signature.rs | 9 - src/test/run-pass/numbers-arithmetic/float.rs | 9 - src/test/run-pass/numbers-arithmetic/float2.rs | 26 - src/test/run-pass/numbers-arithmetic/float_math.rs | 21 - src/test/run-pass/numbers-arithmetic/floatlits.rs | 12 - src/test/run-pass/numbers-arithmetic/i128-ffi.rs | 31 - src/test/run-pass/numbers-arithmetic/i128.rs | 110 - src/test/run-pass/numbers-arithmetic/i32-sub.rs | 6 - src/test/run-pass/numbers-arithmetic/i8-incr.rs | 12 - .../numbers-arithmetic/int-abs-overflow.rs | 13 - src/test/run-pass/numbers-arithmetic/int.rs | 7 - .../numbers-arithmetic/integer-literal-radix.rs | 19 - .../integer-literal-suffix-inference-2.rs | 9 - .../integer-literal-suffix-inference-3.rs | 4 - .../integer-literal-suffix-inference.rs | 60 - .../next-power-of-two-overflow-debug.rs | 27 - .../next-power-of-two-overflow-ndebug.rs | 14 - .../run-pass/numbers-arithmetic/num-wrapping.rs | 447 --- .../numeric-method-autoexport.rs | 25 - .../numbers-arithmetic/promoted_overflow_opt.rs | 9 - .../numbers-arithmetic/saturating-float-casts.rs | 135 - .../run-pass/numbers-arithmetic/shift-near-oflo.rs | 100 - .../numbers-arithmetic/shift-various-types.rs | 48 - src/test/run-pass/numbers-arithmetic/shift.rs | 76 - .../numbers-arithmetic/signed-shift-const-eval.rs | 8 - .../run-pass/numbers-arithmetic/u128-as-f32.rs | 49 - src/test/run-pass/numbers-arithmetic/u128.rs | 121 - src/test/run-pass/numbers-arithmetic/u32-decr.rs | 10 - .../run-pass/numbers-arithmetic/u8-incr-decr.rs | 19 - src/test/run-pass/numbers-arithmetic/u8-incr.rs | 15 - src/test/run-pass/numbers-arithmetic/uint.rs | 7 - .../object-lifetime-default-default-to-static.rs | 35 - .../object-lifetime-default-from-rptr-box.rs | 33 - .../object-lifetime-default-from-rptr-mut.rs | 36 - .../run-pass/object-lifetime-default-from-rptr.rs | 42 - src/test/run-pass/object-method-numbering.rs | 28 - .../run-pass/objects-coerce-freeze-borrored.rs | 40 - ...ects-owned-object-borrowed-method-headerless.rs | 33 - .../run-pass/objects-owned-object-owned-method.rs | 25 - src/test/run-pass/once-move-out-on-heap.rs | 18 - src/test/run-pass/one-tuple.rs | 15 - src/test/run-pass/op-assign-builtins-by-ref.rs | 76 - src/test/run-pass/opeq.rs | 17 - src/test/run-pass/operator-associativity.rs | 4 - src/test/run-pass/operator-multidispatch.rs | 36 - src/test/run-pass/operator-overloading.rs | 81 - src/test/run-pass/optimization-fuel-0.rs | 16 - src/test/run-pass/optimization-fuel-0.stderr | 1 - src/test/run-pass/optimization-fuel-1.rs | 17 - src/test/run-pass/optimization-fuel-1.stderr | 1 - src/test/run-pass/option-ext.rs | 10 - src/test/run-pass/option-unwrap.rs | 32 - src/test/run-pass/out-of-stack.rs | 90 - src/test/run-pass/out-pointer-aliasing.rs | 23 - src/test/run-pass/output-slot-variants.rs | 70 - src/test/run-pass/over-constrained-vregs.rs | 12 - .../overlap-doesnt-conflict-with-specialization.rs | 19 - ...verlap-permitted-for-annotated-marker-traits.rs | 26 - .../auxiliary/overloaded_autoderef_xc.rs | 30 - .../overloaded/overloaded-autoderef-count.rs | 74 - .../overloaded/overloaded-autoderef-indexing.rs | 20 - .../overloaded/overloaded-autoderef-order.rs | 71 - .../overloaded/overloaded-autoderef-vtable.rs | 39 - .../overloaded/overloaded-autoderef-xcrate.rs | 9 - .../run-pass/overloaded/overloaded-autoderef.rs | 45 - .../overloaded/overloaded-calls-object-one-arg.rs | 13 - .../overloaded/overloaded-calls-object-two-args.rs | 13 - .../overloaded-calls-object-zero-args.rs | 13 - .../overloaded/overloaded-calls-param-vtables.rs | 32 - .../run-pass/overloaded/overloaded-calls-simple.rs | 78 - .../overloaded/overloaded-calls-zero-args.rs | 30 - .../run-pass/overloaded/overloaded-deref-count.rs | 78 - src/test/run-pass/overloaded/overloaded-deref.rs | 43 - .../overloaded/overloaded-index-assoc-list.rs | 48 - .../overloaded/overloaded-index-autoderef.rs | 77 - .../overloaded/overloaded-index-in-field.rs | 46 - src/test/run-pass/overloaded/overloaded-index.rs | 64 - .../overloaded_deref_with_ref_pattern.rs | 95 - ...overloaded_deref_with_ref_pattern_issue15609.rs | 37 - src/test/run-pass/owned-implies-static.rs | 8 - src/test/run-pass/packed/auxiliary/packed.rs | 19 - .../packed/packed-struct-borrow-element.rs | 35 - .../run-pass/packed/packed-struct-drop-aligned.rs | 33 - .../packed/packed-struct-generic-layout.rs | 32 - .../run-pass/packed/packed-struct-generic-size.rs | 44 - src/test/run-pass/packed/packed-struct-layout.rs | 28 - src/test/run-pass/packed/packed-struct-match.rs | 45 - .../packed/packed-struct-optimized-enum.rs | 36 - src/test/run-pass/packed/packed-struct-size-xc.rs | 20 - src/test/run-pass/packed/packed-struct-size.rs | 157 - src/test/run-pass/packed/packed-struct-vec.rs | 120 - .../run-pass/packed/packed-tuple-struct-layout.rs | 21 - .../run-pass/packed/packed-tuple-struct-size.rs | 79 - .../packed-with-inference-vars-issue-61402.rs | 22 - .../abort-link-to-unwinding-crates.rs | 41 - src/test/run-pass/panic-runtime/abort.rs | 44 - .../auxiliary/exit-success-if-unwind.rs | 16 - src/test/run-pass/panic-runtime/link-to-abort.rs | 11 - src/test/run-pass/panic-runtime/link-to-unwind.rs | 10 - src/test/run-pass/panic-runtime/lto-abort.rs | 34 - src/test/run-pass/panic-runtime/lto-unwind.rs | 37 - src/test/run-pass/panic-uninitialized-zeroed.rs | 102 - src/test/run-pass/panics/panic-handler-chain.rs | 29 - .../run-pass/panics/panic-handler-flail-wildly.rs | 55 - .../run-pass/panics/panic-handler-set-twice.rs | 24 - .../run-pass/panics/panic-in-dtor-drops-fields.rs | 37 - .../run-pass/panics/panic-recover-propagate.rs | 26 - src/test/run-pass/panics/panic-safe.rs | 51 - src/test/run-pass/paren-free.rs | 7 - src/test/run-pass/parse-assoc-type-lt.rs | 9 - src/test/run-pass/parse-panic.rs | 8 - src/test/run-pass/parser-unicode-whitespace.rs | 12 - src/test/run-pass/path.rs | 8 - src/test/run-pass/paths-containing-nul.rs | 50 - src/test/run-pass/print-stdout-eprint-stderr.rs | 33 - .../privacy/auxiliary/priv-impl-prim-ty.rs | 9 - .../run-pass/privacy/auxiliary/privacy_reexport.rs | 6 - .../privacy/auxiliary/pub_use_mods_xcrate.rs | 10 - .../run-pass/privacy/auxiliary/pub_use_xcrate1.rs | 3 - .../run-pass/privacy/auxiliary/pub_use_xcrate2.rs | 3 - src/test/run-pass/privacy/priv-impl-prim-ty.rs | 11 - src/test/run-pass/privacy/privacy-ns.rs | 114 - src/test/run-pass/privacy/privacy-reexport.rs | 13 - src/test/run-pass/privacy/private-class-field.rs | 26 - src/test/run-pass/privacy/pub-extern-privacy.rs | 18 - src/test/run-pass/privacy/pub-use-xcrate.rs | 15 - .../run-pass/privacy/pub_use_mods_xcrate_exe.rs | 11 - src/test/run-pass/proc-macro/add-impl.rs | 14 - src/test/run-pass/proc-macro/append-impl.rs | 22 - src/test/run-pass/proc-macro/attr-args.rs | 13 - src/test/run-pass/proc-macro/attr-cfg.rs | 27 - src/test/run-pass/proc-macro/attr-on-trait.rs | 19 - src/test/run-pass/proc-macro/auxiliary/add-impl.rs | 21 - .../run-pass/proc-macro/auxiliary/append-impl.rs | 16 - .../run-pass/proc-macro/auxiliary/attr-args.rs | 28 - src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs | 23 - .../run-pass/proc-macro/auxiliary/attr-on-trait.rs | 15 - .../run-pass/proc-macro/auxiliary/bang-macro.rs | 17 - .../run-pass/proc-macro/auxiliary/call-site.rs | 27 - .../proc-macro/auxiliary/count_compound_ops.rs | 32 - .../auxiliary/custom-attr-only-one-derive.rs | 18 - src/test/run-pass/proc-macro/auxiliary/derive-a.rs | 15 - .../run-pass/proc-macro/auxiliary/derive-atob.rs | 15 - .../proc-macro/auxiliary/derive-attr-cfg.rs | 14 - src/test/run-pass/proc-macro/auxiliary/derive-b.rs | 17 - .../run-pass/proc-macro/auxiliary/derive-ctod.rs | 15 - .../proc-macro/auxiliary/derive-nothing.rs | 13 - .../proc-macro/auxiliary/derive-same-struct.rs | 21 - .../proc-macro/auxiliary/derive-two-attrs.rs | 13 - .../run-pass/proc-macro/auxiliary/derive-union.rs | 18 - src/test/run-pass/proc-macro/auxiliary/double.rs | 15 - .../run-pass/proc-macro/auxiliary/empty-crate.rs | 5 - .../proc-macro/auxiliary/expand-with-a-macro.rs | 22 - .../proc-macro/auxiliary/external-crate-var.rs | 40 - .../proc-macro/auxiliary/gen-lifetime-token.rs | 25 - .../proc-macro/auxiliary/hygiene_example.rs | 7 - .../auxiliary/hygiene_example_codegen.rs | 27 - .../run-pass/proc-macro/auxiliary/issue-39889.rs | 17 - .../run-pass/proc-macro/auxiliary/issue-42708.rs | 18 - .../run-pass/proc-macro/auxiliary/issue-50061.rs | 12 - .../run-pass/proc-macro/auxiliary/modify-ast.rs | 47 - .../proc-macro/auxiliary/negative-token.rs | 18 - .../run-pass/proc-macro/auxiliary/not-joint.rs | 30 - .../proc-macro/auxiliary/span-api-tests.rs | 45 - .../proc-macro/auxiliary/span-test-macros.rs | 9 - src/test/run-pass/proc-macro/bang-macro.rs | 11 - src/test/run-pass/proc-macro/call-site.rs | 16 - src/test/run-pass/proc-macro/count_compound_ops.rs | 11 - src/test/run-pass/proc-macro/crate-var.rs | 61 - .../proc-macro/custom-attr-only-one-derive.rs | 16 - src/test/run-pass/proc-macro/derive-attr-cfg.rs | 17 - src/test/run-pass/proc-macro/derive-b.rs | 19 - src/test/run-pass/proc-macro/derive-same-struct.rs | 15 - .../run-pass/proc-macro/derive-same-struct.stdout | 1 - src/test/run-pass/proc-macro/derive-test.rs | 22 - src/test/run-pass/proc-macro/derive-two-attrs.rs | 15 - src/test/run-pass/proc-macro/derive-union.rs | 17 - src/test/run-pass/proc-macro/empty-crate.rs | 9 - .../run-pass/proc-macro/expand-with-a-macro.rs | 20 - src/test/run-pass/proc-macro/gen-lifetime-token.rs | 11 - src/test/run-pass/proc-macro/hygiene_example.rs | 20 - src/test/run-pass/proc-macro/issue-39889.rs | 12 - src/test/run-pass/proc-macro/issue-42708.rs | 26 - src/test/run-pass/proc-macro/issue-50061.rs | 23 - src/test/run-pass/proc-macro/load-two.rs | 23 - src/test/run-pass/proc-macro/modify-ast.rs | 26 - src/test/run-pass/proc-macro/negative-token.rs | 13 - src/test/run-pass/proc-macro/not-joint.rs | 24 - src/test/run-pass/proc-macro/smoke.rs | 20 - src/test/run-pass/proc-macro/span-api-tests.rs | 62 - src/test/run-pass/proc-macro/struct-field-macro.rs | 18 - src/test/run-pass/proc_macro.rs | 39 - src/test/run-pass/process/process-envs.rs | 53 - src/test/run-pass/process/process-exit.rs | 27 - .../run-pass/process/process-remove-from-env.rs | 47 - src/test/run-pass/process/process-sigpipe.rs | 36 - .../run-pass/process/process-spawn-nonexistent.rs | 15 - .../process/process-spawn-with-unicode-params.rs | 77 - .../process/process-status-inherits-stdin.rs | 36 - src/test/run-pass/project-cache-issue-31849.rs | 65 - src/test/run-pass/project-cache-issue-37154.rs | 21 - src/test/run-pass/project-defer-unification.rs | 104 - src/test/run-pass/pure-sum.rs | 53 - src/test/run-pass/purity-infer.rs | 6 - src/test/run-pass/range-type-infer.rs | 22 - src/test/run-pass/range.rs | 51 - src/test/run-pass/range_inclusive.rs | 122 - src/test/run-pass/range_inclusive_gate.rs | 14 - src/test/run-pass/ranges-precedence.rs | 52 - src/test/run-pass/raw-fat-ptr.rs | 118 - src/test/run-pass/raw-str.rs | Bin 847 -> 0 bytes src/test/run-pass/rcvr-borrowed-to-region.rs | 29 - src/test/run-pass/reachable-unnameable-items.rs | 31 - .../run-pass/reachable-unnameable-type-alias.rs | 16 - src/test/run-pass/readalias.rs | 12 - src/test/run-pass/realloc-16687.rs | 183 - src/test/run-pass/reexport-should-still-link.rs | 10 - src/test/run-pass/reexport-star.rs | 16 - src/test/run-pass/reexport-test-harness-main.rs | 11 - .../run-pass/refer-to-other-statics-by-value.rs | 8 - .../regions-addr-of-interior-of-unique-box.rs | 23 - src/test/run-pass/regions/regions-addr-of-ret.rs | 9 - .../regions/regions-assoc-type-region-bound.rs | 22 - .../regions/regions-assoc-type-static-bound.rs | 19 - src/test/run-pass/regions/regions-borrow-at.rs | 13 - .../run-pass/regions/regions-borrow-evec-fixed.rs | 10 - .../run-pass/regions/regions-borrow-evec-uniq.rs | 16 - src/test/run-pass/regions/regions-borrow-uniq.rs | 12 - src/test/run-pass/regions/regions-bot.rs | 11 - .../regions/regions-bound-lists-feature-gate-2.rs | 14 - .../regions/regions-bound-lists-feature-gate.rs | 18 - ...gions-close-over-type-parameter-successfully.rs | 23 - src/test/run-pass/regions/regions-copy-closure.rs | 21 - .../run-pass/regions/regions-creating-enums2.rs | 17 - .../run-pass/regions/regions-creating-enums5.rs | 17 - .../run-pass/regions/regions-debruijn-of-object.rs | 22 - .../run-pass/regions/regions-dependent-addr-of.rs | 113 - .../run-pass/regions/regions-dependent-autofn.rs | 15 - .../regions/regions-dependent-autoslice.rs | 14 - .../run-pass/regions/regions-dependent-let-ref.rs | 12 - .../regions-early-bound-lifetime-in-assoc-fn.rs | 35 - .../regions/regions-early-bound-trait-param.rs | 134 - .../regions-early-bound-used-in-bound-method.rs | 30 - .../regions/regions-early-bound-used-in-bound.rs | 28 - .../regions-early-bound-used-in-type-param.rs | 28 - .../regions/regions-escape-into-other-fn.rs | 10 - src/test/run-pass/regions/regions-expl-self.rs | 15 - .../run-pass/regions/regions-fn-subtyping-2.rs | 20 - src/test/run-pass/regions/regions-fn-subtyping.rs | 30 - ...-region-outlives-static-outlives-free-region.rs | 17 - .../regions/regions-infer-borrow-scope-addr-of.rs | 23 - .../regions/regions-infer-borrow-scope-view.rs | 11 - .../regions-infer-borrow-scope-within-loop-ok.rs | 13 - .../run-pass/regions/regions-infer-borrow-scope.rs | 15 - src/test/run-pass/regions/regions-infer-call-2.rs | 15 - src/test/run-pass/regions/regions-infer-call.rs | 11 - .../regions-infer-contravariance-due-to-ret.rs | 22 - .../regions-infer-reborrow-ref-mut-recurse.rs | 18 - .../regions-infer-region-in-fn-but-not-type.rs | 19 - .../regions/regions-infer-static-from-proc.rs | 18 - src/test/run-pass/regions/regions-issue-21422.rs | 18 - src/test/run-pass/regions/regions-issue-22246.rs | 29 - .../regions/regions-lifetime-nonfree-late-bound.rs | 35 - ...gions-lifetime-static-items-enclosing-scopes.rs | 20 - src/test/run-pass/regions/regions-link-fn-args.rs | 15 - .../run-pass/regions/regions-lub-ref-ref-rc.rs | 28 - src/test/run-pass/regions/regions-mock-codegen.rs | 56 - .../regions-no-bound-in-argument-cleanup.rs | 24 - .../regions-no-variance-from-fn-generics.rs | 44 - .../run-pass/regions/regions-nullary-variant.rs | 15 - src/test/run-pass/regions/regions-params.rs | 19 - .../regions/regions-reassign-let-bound-pointer.rs | 18 - .../regions-reassign-match-bound-pointer.rs | 21 - src/test/run-pass/regions/regions-refcell.rs | 45 - ...d-regions-on-closures-to-inference-variables.rs | 59 - .../regions/regions-return-interior-of-option.rs | 24 - .../regions/regions-scope-chain-example.rs | 43 - src/test/run-pass/regions/regions-self-impls.rs | 20 - src/test/run-pass/regions/regions-self-in-enums.rs | 17 - src/test/run-pass/regions/regions-simple.rs | 7 - .../run-pass/regions/regions-static-closure.rs | 19 - .../run-pass/regions/regions-trait-object-1.rs | 35 - ...ons-variance-contravariant-use-contravariant.rs | 27 - .../regions-variance-covariant-use-covariant.rs | 23 - src/test/run-pass/repeat-expr-in-static.rs | 8 - src/test/run-pass/repr_c_int_align.rs | 46 - src/test/run-pass/resolve-issue-2428.rs | 8 - src/test/run-pass/resolve-pseudo-shadowing.rs | 11 - src/test/run-pass/resource-assign-is-not-copy.rs | 33 - src/test/run-pass/resource-destruct.rs | 31 - src/test/run-pass/result-opt-conversions.rs | 47 - src/test/run-pass/ret-bang.rs | 13 - src/test/run-pass/ret-none.rs | 13 - src/test/run-pass/return-nil.rs | 6 - src/test/run-pass/rfcs/rfc-1014-2.rs | 30 - src/test/run-pass/rfcs/rfc-1014.rs | 34 - .../run-pass/rfcs/rfc-1789-as-cell/from-mut.rs | 11 - .../termination-trait-for-box-dyn-error.rs | 6 - .../termination-trait-for-empty.rs | 2 - .../termination-trait-for-exitcode.rs | 8 - .../termination-trait-for-impl-termination.rs | 4 - .../termination-trait-for-result-box-error_ok.rs | 6 - .../termination-trait-for-result.rs | 6 - .../termination-trait-for-str.rs | 4 - .../rfcs/rfc-2005-default-binding-mode/box.rs | 18 - .../rfcs/rfc-2005-default-binding-mode/constref.rs | 40 - .../rfcs/rfc-2005-default-binding-mode/enum.rs | 45 - .../rfcs/rfc-2005-default-binding-mode/for.rs | 20 - .../rfcs/rfc-2005-default-binding-mode/general.rs | 249 -- .../rfcs/rfc-2005-default-binding-mode/lit.rs | 34 - .../rfcs/rfc-2005-default-binding-mode/range.rs | 9 - .../rfc-2005-default-binding-mode/ref-region.rs | 16 - .../rfc-2005-default-binding-mode/reset-mode.rs | 14 - .../rfcs/rfc-2005-default-binding-mode/slice.rs | 26 - .../rfcs/rfc-2005-default-binding-mode/struct.rs | 22 - .../rfc-2005-default-binding-mode/tuple-struct.rs | 19 - .../rfcs/rfc-2005-default-binding-mode/tuple.rs | 12 - .../rfc-2126-crate-paths/crate-path-absolute.rs | 42 - .../crate-path-absolute.stderr | 8 - .../crate-path-visibility-ambiguity.rs | 15 - .../crate-path-visibility-ambiguity.stderr | 8 - .../auxiliary/xcrate.rs | 7 - .../rfcs/rfc-2126-extern-absolute-paths/basic.rs | 25 - .../rfcs/rfc-2126-extern-absolute-paths/test.rs | 10 - .../rfc-2126-extern-absolute-paths/whitelisted.rs | 14 - .../run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs | 15 - .../rfcs/rfc-2151-raw-identifiers/basic.rs | 20 - .../rfcs/rfc-2151-raw-identifiers/items.rs | 32 - .../rfcs/rfc-2151-raw-identifiers/macros.rs | 38 - .../rfcs/rfc-2175-or-if-while-let/basic.rs | 33 - .../run-pass/rfcs/rfc-2302-self-struct-ctor.rs | 127 - ...-2421-unreserve-pure-offsetof-sizeof-alignof.rs | 15 - .../rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs | 23 - src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs | 17 - src/test/run-pass/rfcs/rfc1623.rs | 75 - .../run-pass/rfcs/rfc1717/auxiliary/clibrary.rs | 5 - src/test/run-pass/rfcs/rfc1717/library-override.rs | 14 - src/test/run-pass/rfcs/rfc1857-drop-order.rs | 224 -- src/test/run-pass/running-with-no-runtime.rs | 51 - src/test/run-pass/rustc-rust-log.rs | 14 - src/test/run-pass/rvalue-static-promotion.rs | 19 - src/test/run-pass/segfault-no-out-of-stack.rs | 50 - src/test/run-pass/semistatement-in-lambda.rs | 12 - .../sepcomp/auxiliary/sepcomp-extern-lib.rs | 4 - .../run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs | 6 - src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs | 21 - src/test/run-pass/sepcomp/sepcomp-cci.rs | 33 - src/test/run-pass/sepcomp/sepcomp-extern.rs | 33 - src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs | 33 - src/test/run-pass/sepcomp/sepcomp-fns.rs | 30 - src/test/run-pass/sepcomp/sepcomp-lib-lto.rs | 18 - src/test/run-pass/sepcomp/sepcomp-lib.rs | 16 - src/test/run-pass/sepcomp/sepcomp-statics.rs | 31 - src/test/run-pass/sepcomp/sepcomp-unwind.rs | 34 - src/test/run-pass/seq-compare.rs | 16 - src/test/run-pass/shadow.rs | 24 - src/test/run-pass/shadowed-use-visibility.rs | 13 - src/test/run-pass/shebang.rs | 5 - .../run-pass/signal-alternate-stack-cleanup.rs | 37 - src/test/run-pass/signal-exit-status.rs | 19 - src/test/run-pass/sigpipe-should-be-ignored.rs | 34 - src/test/run-pass/simd/simd-generics.rs | 39 - .../run-pass/simd/simd-intrinsic-float-math.rs | 103 - .../run-pass/simd/simd-intrinsic-float-minmax.rs | 54 - ...simd-intrinsic-generic-arithmetic-saturating.rs | 92 - .../simd/simd-intrinsic-generic-arithmetic.rs | 120 - .../simd/simd-intrinsic-generic-bitmask.rs | 61 - .../run-pass/simd/simd-intrinsic-generic-cast.rs | 121 - .../simd/simd-intrinsic-generic-comparison.rs | 106 - .../simd/simd-intrinsic-generic-elements.rs | 125 - .../run-pass/simd/simd-intrinsic-generic-gather.rs | 141 - .../simd/simd-intrinsic-generic-reduction.rs | 165 - .../run-pass/simd/simd-intrinsic-generic-select.rs | 173 - src/test/run-pass/simd/simd-size-align.rs | 96 - .../run-pass/simd/simd-target-feature-mixup.rs | 185 - src/test/run-pass/simd/simd-type.rs | 16 - src/test/run-pass/simple-infer.rs | 6 - src/test/run-pass/simple_global_asm.rs | 24 - src/test/run-pass/size-and-align.rs | 20 - src/test/run-pass/sized-borrowed-pointer.rs | 10 - src/test/run-pass/sized-owned-pointer.rs | 11 - src/test/run-pass/sleep.rs | 19 - src/test/run-pass/slowparse-bstring.rs | 6 - src/test/run-pass/slowparse-string.rs | 6 - .../specialization/assoc-ty-graph-cycle.rs | 25 - .../auxiliary/cross_crates_defaults.rs | 38 - .../run-pass/specialization/auxiliary/go_trait.rs | 43 - .../auxiliary/specialization_cross_crate.rs | 72 - .../specialization/cross-crate-defaults.rs | 41 - .../defaultimpl/allowed-cross-crate.rs | 26 - .../defaultimpl/auxiliary/go_trait.rs | 43 - .../specialization/defaultimpl/out-of-order.rs | 19 - .../defaultimpl/overlap-projection.rs | 25 - .../specialization/defaultimpl/projection.rs | 42 - src/test/run-pass/specialization/issue-50452.rs | 19 - .../specialization-allowed-cross-crate.rs | 26 - .../specialization/specialization-assoc-fns.rs | 29 - .../specialization/specialization-basics.rs | 98 - .../specialization-cross-crate-no-gate.rs | 21 - .../specialization/specialization-cross-crate.rs | 50 - .../specialization-default-methods.rs | 86 - .../specialization/specialization-on-projection.rs | 24 - .../specialization/specialization-out-of-order.rs | 19 - .../specialization-overlap-projection.rs | 25 - .../specialization-projection-alias.rs | 26 - .../specialization/specialization-projection.rs | 42 - .../specialization/specialization-super-traits.rs | 17 - ...ization-translate-projections-with-lifetimes.rs | 33 - ...ialization-translate-projections-with-params.rs | 32 - .../specialization-translate-projections.rs | 33 - src/test/run-pass/sse2.rs | 26 - src/test/run-pass/stable-addr-of.rs | 8 - src/test/run-pass/stack-probes-lto.rs | 19 - src/test/run-pass/stack-probes.rs | 68 - .../auxiliary/static-function-pointer-aux.rs | 4 - .../statics/auxiliary/static-methods-crate.rs | 29 - .../statics/auxiliary/static_fn_inline_xc_aux.rs | 12 - .../statics/auxiliary/static_fn_trait_xc_aux.rs | 11 - .../run-pass/statics/auxiliary/static_mut_xc.rs | 1 - src/test/run-pass/statics/static-fn-inline-xc.rs | 12 - src/test/run-pass/statics/static-fn-trait-xc.rs | 12 - .../run-pass/statics/static-function-pointer-xc.rs | 17 - .../run-pass/statics/static-function-pointer.rs | 16 - src/test/run-pass/statics/static-impl.rs | 66 - .../static-method-in-trait-with-tps-intracrate.rs | 28 - src/test/run-pass/statics/static-method-xcrate.rs | 13 - .../run-pass/statics/static-methods-in-traits.rs | 26 - .../run-pass/statics/static-methods-in-traits2.rs | 22 - src/test/run-pass/statics/static-mut-foreign.rs | 41 - src/test/run-pass/statics/static-mut-xc.rs | 39 - src/test/run-pass/statics/static-recursive.rs | 36 - src/test/run-pass/stdio-is-blocking.rs | 85 - src/test/run-pass/str-concat.rs | 9 - src/test/run-pass/str-multiline.rs | 13 - src/test/run-pass/string-box-error.rs | 12 - src/test/run-pass/string-escapes.rs | 7 - src/test/run-pass/struct-ctor-mangling.rs | 14 - src/test/run-pass/structs-enums/align-enum.rs | 54 - src/test/run-pass/structs-enums/align-struct.rs | 245 -- .../run-pass/structs-enums/auxiliary/cci_class.rs | 14 - .../structs-enums/auxiliary/cci_class_2.rs | 19 - .../structs-enums/auxiliary/cci_class_3.rs | 19 - .../structs-enums/auxiliary/cci_class_4.rs | 41 - .../structs-enums/auxiliary/cci_class_6.rs | 25 - .../structs-enums/auxiliary/cci_class_cast.rs | 50 - .../structs-enums/auxiliary/cci_class_trait.rs | 5 - .../structs-enums/auxiliary/empty-struct.rs | 9 - .../auxiliary/namespaced_enum_emulate_flat.rs | 25 - .../structs-enums/auxiliary/namespaced_enums.rs | 10 - .../structs-enums/auxiliary/newtype_struct_xc.rs | 3 - .../auxiliary/struct_destructuring_cross_crate.rs | 6 - .../auxiliary/struct_variant_xc_aux.rs | 8 - .../auxiliary/xcrate_struct_aliases.rs | 6 - .../run-pass/structs-enums/borrow-tuple-fields.rs | 38 - .../class-cast-to-trait-cross-crate-2.rs | 20 - .../class-cast-to-trait-multiple-types.rs | 93 - .../run-pass/structs-enums/class-cast-to-trait.rs | 60 - src/test/run-pass/structs-enums/class-dtor.rs | 25 - src/test/run-pass/structs-enums/class-exports.rs | 31 - .../class-impl-very-parameterized-trait.rs | 107 - .../class-implement-trait-cross-crate.rs | 59 - .../structs-enums/class-implement-traits.rs | 63 - .../structs-enums/class-method-cross-crate.rs | 13 - .../structs-enums/class-methods-cross-crate.rs | 14 - src/test/run-pass/structs-enums/class-methods.rs | 30 - .../class-poly-methods-cross-crate.rs | 16 - .../run-pass/structs-enums/class-poly-methods.rs | 37 - .../run-pass/structs-enums/class-separate-impl.rs | 65 - src/test/run-pass/structs-enums/class-str-field.rs | 21 - src/test/run-pass/structs-enums/class-typarams.rs | 32 - .../run-pass/structs-enums/classes-cross-crate.rs | 13 - .../structs-enums/classes-self-referential.rs | 20 - .../structs-enums/classes-simple-cross-crate.rs | 12 - .../structs-enums/classes-simple-method.rs | 28 - src/test/run-pass/structs-enums/classes-simple.rs | 23 - src/test/run-pass/structs-enums/classes.rs | 51 - .../structs-enums/codegen-tag-static-padding.rs | 59 - .../structs-enums/compare-generic-enums.rs | 16 - .../structs-enums/discrim-explicit-23030.rs | 147 - .../run-pass/structs-enums/empty-struct-braces.rs | 213 -- src/test/run-pass/structs-enums/empty-tag.rs | 21 - src/test/run-pass/structs-enums/enum-alignment.rs | 24 - .../structs-enums/enum-clike-ffi-as-int.rs | 33 - src/test/run-pass/structs-enums/enum-discr.rs | 23 - .../structs-enums/enum-discrim-autosizing.rs | 53 - .../structs-enums/enum-discrim-manual-sizing.rs | 111 - .../structs-enums/enum-discrim-range-overflow.rs | 26 - .../structs-enums/enum-discrim-width-stuff.rs | 44 - .../run-pass/structs-enums/enum-disr-val-pretty.rs | 17 - .../structs-enums/enum-export-inheritance.rs | 15 - .../structs-enums/enum-layout-optimization.rs | 50 - .../enum-non-c-like-repr-c-and-int.rs | 171 - .../structs-enums/enum-non-c-like-repr-c.rs | 171 - .../structs-enums/enum-non-c-like-repr-int.rs | 167 - .../structs-enums/enum-null-pointer-opt.rs | 74 - .../enum-nullable-const-null-with-fields.rs | 13 - .../enum-nullable-simplifycfg-misopt.rs | 17 - .../run-pass/structs-enums/enum-univariant-repr.rs | 51 - src/test/run-pass/structs-enums/enum-variants.rs | 18 - .../run-pass/structs-enums/enum-vec-initializer.rs | 17 - .../run-pass/structs-enums/export-abstract-tag.rs | 15 - .../run-pass/structs-enums/export-tag-variant.rs | 9 - src/test/run-pass/structs-enums/expr-if-struct.rs | 32 - .../run-pass/structs-enums/expr-match-struct.rs | 31 - .../structs-enums/field-destruction-order.rs | 47 - src/test/run-pass/structs-enums/foreign-struct.rs | 19 - .../structs-enums/functional-struct-upd.rs | 12 - src/test/run-pass/structs-enums/ivec-tag.rs | 22 - .../module-qualified-struct-destructure.rs | 14 - .../namespaced-enum-emulate-flat-xc.rs | 25 - .../structs-enums/namespaced-enum-emulate-flat.rs | 44 - .../namespaced-enum-glob-import-xcrate.rs | 26 - .../structs-enums/namespaced-enum-glob-import.rs | 35 - .../structs-enums/namespaced-enums-xcrate.rs | 16 - .../run-pass/structs-enums/namespaced-enums.rs | 17 - .../structs-enums/nested-enum-same-names.rs | 27 - .../structs-enums/newtype-struct-drop-run.rs | 21 - .../structs-enums/newtype-struct-with-dtor.rs | 20 - .../run-pass/structs-enums/newtype-struct-xc-2.rs | 15 - .../run-pass/structs-enums/newtype-struct-xc.rs | 10 - src/test/run-pass/structs-enums/nonzero-enum.rs | 30 - src/test/run-pass/structs-enums/numeric-fields.rs | 12 - .../object-lifetime-default-from-ref-struct.rs | 58 - .../object-lifetime-default-from-rptr-struct.rs | 37 - src/test/run-pass/structs-enums/rec-align-u32.rs | 56 - src/test/run-pass/structs-enums/rec-align-u64.rs | 101 - src/test/run-pass/structs-enums/rec-auto.rs | 14 - src/test/run-pass/structs-enums/rec-extend.rs | 18 - src/test/run-pass/structs-enums/rec-tup.rs | 31 - src/test/run-pass/structs-enums/rec.rs | 24 - src/test/run-pass/structs-enums/record-pat.rs | 19 - .../run-pass/structs-enums/resource-in-struct.rs | 37 - .../run-pass/structs-enums/simple-generic-tag.rs | 11 - .../structs-enums/simple-match-generic-tag.rs | 13 - .../structs-enums/small-enum-range-edge.rs | 27 - .../structs-enums/small-enums-with-fields.rs | 33 - .../structs-enums/struct-aliases-xcrate.rs | 25 - src/test/run-pass/structs-enums/struct-aliases.rs | 64 - .../struct-destructuring-cross-crate.rs | 12 - .../structs-enums/struct-field-shorthand.rs | 26 - .../structs-enums/struct-like-variant-construct.rs | 18 - .../structs-enums/struct-like-variant-match.rs | 33 - .../struct-lit-functional-no-fields.rs | 26 - .../run-pass/structs-enums/struct-literal-dtor.rs | 18 - .../structs-enums/struct-new-as-field-name.rs | 10 - .../structs-enums/struct-order-of-eval-1.rs | 16 - .../structs-enums/struct-order-of-eval-2.rs | 16 - .../structs-enums/struct-order-of-eval-3.rs | 37 - .../structs-enums/struct-order-of-eval-4.rs | 34 - .../structs-enums/struct-partial-move-1.rs | 21 - .../structs-enums/struct-partial-move-2.rs | 28 - .../structs-enums/struct-path-associated-type.rs | 27 - .../run-pass/structs-enums/struct-path-self.rs | 45 - .../structs-enums/struct-pattern-matching.rs | 18 - src/test/run-pass/structs-enums/struct-return.rs | 64 - .../struct-variant-field-visibility.rs | 17 - .../run-pass/structs-enums/struct_variant_xc.rs | 11 - .../structs-enums/struct_variant_xc_match.rs | 14 - .../run-pass/structs-enums/tag-align-dyn-u64.rs | 29 - .../structs-enums/tag-align-dyn-variants.rs | 67 - src/test/run-pass/structs-enums/tag-align-shape.rs | 20 - src/test/run-pass/structs-enums/tag-align-u64.rs | 29 - .../run-pass/structs-enums/tag-disr-val-shape.rs | 20 - src/test/run-pass/structs-enums/tag-exports.rs | 21 - src/test/run-pass/structs-enums/tag-in-block.rs | 15 - .../tag-variant-disr-type-mismatch.rs | 12 - .../run-pass/structs-enums/tag-variant-disr-val.rs | 66 - src/test/run-pass/structs-enums/tag.rs | 30 - .../structs-enums/tuple-struct-construct.rs | 8 - .../tuple-struct-constructor-pointer.rs | 12 - .../structs-enums/tuple-struct-destructuring.rs | 10 - .../structs-enums/tuple-struct-matching.rs | 13 - .../run-pass/structs-enums/tuple-struct-trivial.rs | 8 - .../structs-enums/uninstantiable-struct.rs | 4 - .../structs-enums/unit-like-struct-drop-run.rs | 23 - .../run-pass/structs-enums/unit-like-struct.rs | 9 - .../structs-enums/variant-structs-trivial.rs | 10 - src/test/run-pass/structured-compare.rs | 30 - src/test/run-pass/super-fast-paren-parsing.rs | 24 - src/test/run-pass/super.rs | 16 - src/test/run-pass/supported-cast.rs | 206 -- src/test/run-pass/svh-add-nothing.rs | 14 - src/test/run-pass/swap-1.rs | 10 - src/test/run-pass/swap-2.rs | 14 - src/test/run-pass/swap-overlapping.rs | 44 - src/test/run-pass/tail-call-arg-leak.rs | 9 - src/test/run-pass/tail-cps.rs | 17 - src/test/run-pass/tail-direct.rs | 7 - src/test/run-pass/tcp-stress.rs | 66 - src/test/run-pass/terminate-in-initializer.rs | 33 - .../test-allow-dead-extern-static-no-warning.rs | 11 - src/test/run-pass/test-allow-fail-attr.rs | 16 - ...nature-verification-for-explicit-return-type.rs | 12 - src/test/run-pass/test-main-not-dead-attr.rs | 9 - src/test/run-pass/test-main-not-dead.rs | 6 - src/test/run-pass/test-runner-hides-buried-main.rs | 15 - src/test/run-pass/test-runner-hides-main.rs | 5 - src/test/run-pass/test-runner-hides-start.rs | 7 - src/test/run-pass/test-should-fail-good-message.rs | 14 - src/test/run-pass/test-vs-cfg-test.rs | 9 - src/test/run-pass/thin-lto-global-allocator.rs | 7 - src/test/run-pass/thinlto/all-crates.rs | 8 - src/test/run-pass/thinlto/auxiliary/dylib.rs | 6 - .../run-pass/thinlto/auxiliary/msvc-imp-present.rs | 11 - .../thinlto/auxiliary/thin-lto-inlines-aux.rs | 7 - src/test/run-pass/thinlto/dylib-works.rs | 9 - src/test/run-pass/thinlto/msvc-imp-present.rs | 22 - src/test/run-pass/thinlto/thin-lto-inlines.rs | 30 - src/test/run-pass/thinlto/thin-lto-inlines2.rs | 28 - src/test/run-pass/thinlto/weak-works.rs | 28 - src/test/run-pass/thread-local-not-in-prelude.rs | 10 - .../auxiliary/thread-local-extern-static.rs | 10 - src/test/run-pass/threads-sendsync/comm.rs | 22 - .../threads-sendsync/send-is-not-static-par-for.rs | 34 - .../run-pass/threads-sendsync/send-resource.rs | 39 - .../threads-sendsync/send-type-inference.rs | 19 - .../run-pass/threads-sendsync/send_str_hashmap.rs | 53 - .../run-pass/threads-sendsync/send_str_treemap.rs | 58 - .../run-pass/threads-sendsync/sendable-class.rs | 28 - .../run-pass/threads-sendsync/sendfn-is-a-block.rs | 11 - .../threads-sendsync/sendfn-spawn-with-fn-arg.rs | 23 - src/test/run-pass/threads-sendsync/spawn-fn.rs | 25 - src/test/run-pass/threads-sendsync/spawn-types.rs | 25 - src/test/run-pass/threads-sendsync/spawn.rs | 10 - src/test/run-pass/threads-sendsync/spawn2.rs | 31 - .../threads-sendsync/spawning-with-debug.rs | 15 - .../threads-sendsync/std-sync-right-kind-impls.rs | 16 - .../run-pass/threads-sendsync/sync-send-atomics.rs | 14 - .../run-pass/threads-sendsync/sync-send-in-std.rs | 25 - .../sync-send-iterators-in-libcollections.rs | 71 - .../sync-send-iterators-in-libcore.rs | 104 - src/test/run-pass/threads-sendsync/task-comm-0.rs | 30 - src/test/run-pass/threads-sendsync/task-comm-1.rs | 14 - src/test/run-pass/threads-sendsync/task-comm-10.rs | 33 - src/test/run-pass/threads-sendsync/task-comm-11.rs | 21 - src/test/run-pass/threads-sendsync/task-comm-12.rs | 29 - src/test/run-pass/threads-sendsync/task-comm-13.rs | 18 - src/test/run-pass/threads-sendsync/task-comm-14.rs | 36 - src/test/run-pass/threads-sendsync/task-comm-15.rs | 28 - src/test/run-pass/threads-sendsync/task-comm-16.rs | 111 - src/test/run-pass/threads-sendsync/task-comm-17.rs | 17 - src/test/run-pass/threads-sendsync/task-comm-3.rs | 63 - src/test/run-pass/threads-sendsync/task-comm-4.rs | 45 - src/test/run-pass/threads-sendsync/task-comm-5.rs | 17 - src/test/run-pass/threads-sendsync/task-comm-6.rs | 42 - src/test/run-pass/threads-sendsync/task-comm-7.rs | 59 - src/test/run-pass/threads-sendsync/task-comm-9.rs | 35 - .../threads-sendsync/task-comm-chan-nil.rs | 13 - src/test/run-pass/threads-sendsync/task-life-0.rs | 14 - .../threads-sendsync/task-spawn-move-and-copy.rs | 25 - src/test/run-pass/threads-sendsync/task-stderr.rs | 32 - .../threads-sendsync/thread-local-extern-static.rs | 27 - .../threads-sendsync/thread-local-syntax.rs | 22 - src/test/run-pass/threads-sendsync/threads.rs | 16 - .../tls-dtors-are-run-in-a-static-binary.rs | 22 - .../run-pass/threads-sendsync/tls-init-on-init.rs | 44 - src/test/run-pass/threads-sendsync/tls-try-with.rs | 30 - src/test/run-pass/tool_attributes.rs | 13 - src/test/run-pass/tool_lints_2018_preview.rs | 7 - src/test/run-pass/trailing-comma.rs | 37 - .../run-pass/traits/anon-trait-static-method.rs | 15 - .../traits/anon_trait_static_method_exe.rs | 12 - src/test/run-pass/traits/assignability-trait.rs | 47 - .../traits/astconv-cycle-between-trait-and-type.rs | 29 - .../run-pass/traits/augmented-assignments-trait.rs | 12 - src/test/run-pass/traits/auto-traits.rs | 31 - .../auxiliary/anon_trait_static_method_lib.rs | 9 - src/test/run-pass/traits/auxiliary/go_trait.rs | 43 - src/test/run-pass/traits/auxiliary/trait_alias.rs | 13 - .../auxiliary/trait_default_method_xc_aux.rs | 40 - .../auxiliary/trait_default_method_xc_aux_2.rs | 17 - .../auxiliary/trait_inheritance_auto_xc_2_aux.rs | 9 - .../auxiliary/trait_inheritance_auto_xc_aux.rs | 7 - .../auxiliary/trait_inheritance_overloading_xc.rs | 38 - .../run-pass/traits/auxiliary/trait_xc_call_aux.rs | 11 - src/test/run-pass/traits/auxiliary/traitimpl.rs | 7 - src/test/run-pass/traits/cycle-trait-type-trait.rs | 25 - .../traits/default-method-supertrait-vtable.rs | 28 - src/test/run-pass/traits/dyn-trait.rs | 17 - src/test/run-pass/traits/fmt-pointer-trait.rs | 24 - src/test/run-pass/traits/impl-implicit-trait.rs | 26 - .../traits/impl-inherent-prefer-over-trait.rs | 30 - .../traits/infer-from-object-trait-issue-26952.rs | 26 - .../run-pass/traits/inherent-trait-method-order.rs | 25 - .../traits/kindck-owned-trait-contains-1.rs | 23 - src/test/run-pass/traits/multiple-trait-bounds.rs | 9 - .../run-pass/traits/object-one-type-two-traits.rs | 33 - .../overlap-permitted-for-marker-traits-neg.rs | 12 - .../traits/overlap-permitted-for-marker-traits.rs | 27 - .../traits/parameterized-trait-with-bounds.rs | 21 - .../traits/principal-less-trait-objects.rs | 42 - .../run-pass/traits/supertrait-default-generics.rs | 39 - src/test/run-pass/traits/syntax-trait-polarity.rs | 21 - .../traits/trait-alias-import-cross-crate.rs | 14 - src/test/run-pass/traits/trait-alias-import.rs | 40 - src/test/run-pass/traits/trait-bounds-basic.rs | 25 - .../trait-bounds-impl-comparison-duplicates.rs | 16 - src/test/run-pass/traits/trait-bounds-in-arc.rs | 109 - src/test/run-pass/traits/trait-bounds-recursion.rs | 20 - src/test/run-pass/traits/trait-bounds.rs | 30 - .../run-pass/traits/trait-cache-issue-18209.rs | 20 - src/test/run-pass/traits/trait-coercion-generic.rs | 25 - src/test/run-pass/traits/trait-coercion.rs | 36 - .../run-pass/traits/trait-composition-trivial.rs | 12 - src/test/run-pass/traits/trait-copy-guessing.rs | 38 - .../traits/trait-default-method-bound-subst.rs | 18 - .../traits/trait-default-method-bound-subst2.rs | 16 - .../traits/trait-default-method-bound-subst3.rs | 17 - .../traits/trait-default-method-bound-subst4.rs | 19 - .../run-pass/traits/trait-default-method-bound.rs | 16 - .../run-pass/traits/trait-default-method-xc-2.rs | 26 - .../run-pass/traits/trait-default-method-xc.rs | 81 - ...t-false-ambiguity-where-clause-builtin-bound.rs | 16 - src/test/run-pass/traits/trait-generic.rs | 45 - src/test/run-pass/traits/trait-impl-2.rs | 19 - src/test/run-pass/traits/trait-impl.rs | 41 - .../run-pass/traits/trait-inheritance-auto-xc-2.rs | 23 - .../run-pass/traits/trait-inheritance-auto-xc.rs | 25 - src/test/run-pass/traits/trait-inheritance-auto.rs | 29 - .../trait-inheritance-call-bound-inherited.rs | 20 - .../trait-inheritance-call-bound-inherited2.rs | 23 - ...-inheritance-cast-without-call-to-supertrait.rs | 33 - src/test/run-pass/traits/trait-inheritance-cast.rs | 33 - .../trait-inheritance-cross-trait-call-xc.rs | 20 - .../traits/trait-inheritance-cross-trait-call.rs | 19 - .../run-pass/traits/trait-inheritance-diamond.rs | 28 - .../trait-inheritance-multiple-inheritors.rs | 23 - .../traits/trait-inheritance-multiple-params.rs | 26 - src/test/run-pass/traits/trait-inheritance-num.rs | 13 - src/test/run-pass/traits/trait-inheritance-num0.rs | 24 - src/test/run-pass/traits/trait-inheritance-num1.rs | 15 - src/test/run-pass/traits/trait-inheritance-num2.rs | 86 - src/test/run-pass/traits/trait-inheritance-num3.rs | 19 - src/test/run-pass/traits/trait-inheritance-num5.rs | 26 - .../traits/trait-inheritance-overloading-simple.rs | 27 - .../traits/trait-inheritance-overloading-xc-exe.rs | 20 - .../traits/trait-inheritance-overloading.rs | 47 - .../traits/trait-inheritance-self-in-supertype.rs | 62 - src/test/run-pass/traits/trait-inheritance-self.rs | 29 - .../run-pass/traits/trait-inheritance-simple.rs | 24 - .../run-pass/traits/trait-inheritance-static.rs | 26 - .../run-pass/traits/trait-inheritance-static2.rs | 29 - .../run-pass/traits/trait-inheritance-subst.rs | 27 - .../run-pass/traits/trait-inheritance-subst2.rs | 37 - .../traits/trait-inheritance-visibility.rs | 20 - src/test/run-pass/traits/trait-inheritance2.rs | 26 - .../run-pass/traits/trait-item-inside-macro.rs | 30 - .../run-pass/traits/trait-object-auto-dedup.rs | 46 - src/test/run-pass/traits/trait-object-exclusion.rs | 19 - src/test/run-pass/traits/trait-object-generics.rs | 43 - .../run-pass/traits/trait-object-lifetime-first.rs | 13 - .../traits/trait-object-with-lifetime-bound.rs | 34 - .../run-pass/traits/trait-region-pointer-simple.rs | 21 - src/test/run-pass/traits/trait-safety-ok-cc.rs | 24 - src/test/run-pass/traits/trait-safety-ok.rs | 18 - .../traits/trait-static-method-overwriting.rs | 34 - src/test/run-pass/traits/trait-to-str.rs | 36 - .../run-pass/traits/trait-where-clause-vs-impl.rs | 45 - .../run-pass/traits/trait-with-bounds-default.rs | 32 - .../traits/traits-assoc-type-in-supertrait.rs | 23 - .../run-pass/traits/traits-conditional-dispatch.rs | 35 - .../run-pass/traits/traits-conditional-model-fn.rs | 60 - .../run-pass/traits/traits-default-method-macro.rs | 20 - .../run-pass/traits/traits-default-method-mut.rs | 11 - .../run-pass/traits/traits-default-method-self.rs | 18 - .../traits/traits-default-method-trivial.rs | 21 - .../traits/traits-elaborate-type-region.rs | 49 - .../traits-impl-object-overlap-issue-23853.rs | 18 - src/test/run-pass/traits/traits-issue-22019.rs | 34 - src/test/run-pass/traits/traits-issue-22110.rs | 27 - src/test/run-pass/traits/traits-issue-22655.rs | 23 - src/test/run-pass/traits/traits-issue-23003.rs | 32 - src/test/run-pass/traits/traits-issue-26339.rs | 31 - .../traits-multidispatch-infer-convert-target.rs | 36 - .../run-pass/traits/traits-repeated-supertrait.rs | 48 - src/test/run-pass/traits/ufcs-trait-object.rs | 17 - src/test/run-pass/traits/use-trait-before-def.rs | 10 - .../transmute-non-immediate-to-immediate.rs | 11 - src/test/run-pass/transmute-specialization.rs | 15 - src/test/run-pass/trivial-message.rs | 16 - src/test/run-pass/try-block.rs | 75 - src/test/run-pass/try-from-int-error-partial-eq.rs | 12 - src/test/run-pass/try-is-identifier-edition2015.rs | 11 - src/test/run-pass/try-operator-custom.rs | 63 - src/test/run-pass/try-operator-hygiene.rs | 26 - src/test/run-pass/try-operator.rs | 193 -- src/test/run-pass/try-wait.rs | 61 - src/test/run-pass/try_from.rs | 37 - src/test/run-pass/tup.rs | 21 - src/test/run-pass/tuple-index-fat-types.rs | 13 - src/test/run-pass/tuple-index.rs | 32 - src/test/run-pass/tydesc-name.rs | 14 - src/test/run-pass/type-ascription.rs | 39 - src/test/run-pass/type-id-higher-rank-2.rs | 31 - src/test/run-pass/type-id-higher-rank.rs | 72 - src/test/run-pass/type-in-nested-module.rs | 17 - src/test/run-pass/type-infer-generalize-ty-var.rs | 56 - src/test/run-pass/type-namespace.rs | 7 - src/test/run-pass/type-param-constraints.rs | 39 - src/test/run-pass/type-param.rs | 11 - src/test/run-pass/type-params-in-for-each.rs | 23 - src/test/run-pass/type-ptr.rs | 10 - src/test/run-pass/type-sizes.rs | 116 - src/test/run-pass/type-use-i1-versus-i8.rs | 12 - .../run-pass/typeck-closure-to-unsafe-fn-ptr.rs | 9 - src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs | 12 - src/test/run-pass/typeck_type_placeholder_1.rs | 32 - src/test/run-pass/typeclasses-eq-example-static.rs | 69 - src/test/run-pass/typeclasses-eq-example.rs | 65 - src/test/run-pass/typeid-intrinsic.rs | 87 - src/test/run-pass/typestate-cfg-nesting.rs | 20 - src/test/run-pass/typestate-multi-decl.rs | 7 - src/test/run-pass/ufcs-polymorphic-paths.rs | 154 - src/test/run-pass/ufcs-type-params.rs | 15 - src/test/run-pass/unary-minus-suffix-inference.rs | 23 - .../auxiliary/unboxed-closures-cross-crate.rs | 16 - .../unboxed-closures-all-traits.rs | 21 - .../unboxed-closures-blanket-fn-mut.rs | 27 - .../unboxed-closures-blanket-fn.rs | 27 - .../unboxed-closures/unboxed-closures-boxed.rs | 16 - .../unboxed-closures/unboxed-closures-by-ref.rs | 24 - .../unboxed-closures-call-fn-autoderef.rs | 18 - .../unboxed-closures-call-sugar-autoderef.rs | 15 - ...unboxed-closures-call-sugar-object-autoderef.rs | 15 - .../unboxed-closures-call-sugar-object.rs | 13 - .../unboxed-closures-counter-not-moved.rs | 28 - .../unboxed-closures-cross-crate.rs | 14 - .../unboxed-closures-direct-sugary-call.rs | 8 - .../unboxed-closures/unboxed-closures-drop.rs | 117 - .../unboxed-closures-extern-fn-hr.rs | 31 - .../unboxed-closures/unboxed-closures-extern-fn.rs | 27 - .../unboxed-closures-fn-as-fnmut-and-fnonce.rs | 44 - .../unboxed-closures-fnmut-as-fnonce.rs | 33 - .../unboxed-closures/unboxed-closures-generic.rs | 13 - ...closures-infer-arg-types-from-expected-bound.rs | 23 - ...es-infer-arg-types-from-expected-object-type.rs | 19 - ...r-arg-types-w-bound-regs-from-expected-bound.rs | 23 - .../unboxed-closures-infer-explicit-call-early.rs | 8 - .../unboxed-closures-infer-fnmut-calling-fnmut.rs | 19 - .../unboxed-closures-infer-fnmut-move.rs | 16 - .../unboxed-closures-infer-fnmut.rs | 15 - .../unboxed-closures-infer-fnonce-move.rs | 25 - .../unboxed-closures-infer-fnonce.rs | 25 - .../unboxed-closures-infer-kind.rs | 27 - .../unboxed-closures-infer-recursive-fn.rs | 45 - .../unboxed-closures-infer-upvar.rs | 13 - .../unboxed-closures-manual-impl.rs | 31 - .../unboxed-closures-monomorphization.rs | 26 - ...ed-closures-move-from-projection-issue-30046.rs | 26 - .../unboxed-closures-move-mutable.rs | 30 - ...-closures-move-some-upvars-in-by-ref-closure.rs | 23 - .../unboxed-closures/unboxed-closures-prelude.rs | 18 - .../unboxed-closures/unboxed-closures-simple.rs | 10 - .../unboxed-closures-single-word-env.rs | 22 - .../unboxed-closures-static-call-fn-once.rs | 7 - .../unboxed-closures-sugar-object.rs | 25 - .../unboxed-closures-unique-type-id.rs | 25 - .../unboxed-closures/unboxed-closures-zero-args.rs | 8 - src/test/run-pass/underscore-lifetimes.rs | 38 - .../run-pass/underscore-method-after-integer.rs | 11 - .../uniform-paths/auxiliary/issue-53691.rs | 7 - src/test/run-pass/uniform-paths/basic-nested.rs | 61 - src/test/run-pass/uniform-paths/basic.rs | 33 - src/test/run-pass/uniform-paths/issue-53691.rs | 9 - src/test/run-pass/uniform-paths/macros-nested.rs | 53 - src/test/run-pass/uniform-paths/macros.rs | 36 - src/test/run-pass/uniform-paths/same-crate.rs | 98 - src/test/run-pass/unify-return-ty.rs | 16 - src/test/run-pass/uninit-empty-types.rs | 17 - src/test/run-pass/union/auxiliary/union.rs | 4 - src/test/run-pass/union/union-align.rs | 63 - src/test/run-pass/union/union-backcomp.rs | 25 - src/test/run-pass/union/union-basic.rs | 59 - src/test/run-pass/union/union-c-interop.rs | 37 - src/test/run-pass/union/union-const-codegen.rs | 17 - src/test/run-pass/union/union-const-eval-field.rs | 45 - src/test/run-pass/union/union-drop-assign.rs | 38 - src/test/run-pass/union/union-drop.rs | 60 - src/test/run-pass/union/union-inherent-method.rs | 14 - src/test/run-pass/union/union-macro.rs | 24 - src/test/run-pass/union/union-nodrop.rs | 59 - src/test/run-pass/union/union-nonzero.rs | 51 - src/test/run-pass/union/union-overwrite.rs | 73 - src/test/run-pass/union/union-packed.rs | 171 - src/test/run-pass/union/union-pat-refutability.rs | 54 - src/test/run-pass/union/union-trait-impl.rs | 17 - src/test/run-pass/union/union-transmute.rs | 28 - src/test/run-pass/unique/unique-assign-copy.rs | 13 - src/test/run-pass/unique/unique-assign-drop.rs | 12 - src/test/run-pass/unique/unique-assign-generic.rs | 12 - src/test/run-pass/unique/unique-assign.rs | 9 - src/test/run-pass/unique/unique-autoderef-field.rs | 11 - src/test/run-pass/unique/unique-autoderef-index.rs | 7 - src/test/run-pass/unique/unique-cmp.rs | 12 - src/test/run-pass/unique/unique-containing-tag.rs | 27 - src/test/run-pass/unique/unique-create.rs | 13 - src/test/run-pass/unique/unique-decl-init-copy.rs | 12 - src/test/run-pass/unique/unique-decl-init.rs | 8 - src/test/run-pass/unique/unique-decl-move.rs | 8 - src/test/run-pass/unique/unique-decl.rs | 11 - src/test/run-pass/unique/unique-deref.rs | 7 - src/test/run-pass/unique/unique-destructure.rs | 10 - src/test/run-pass/unique/unique-drop-complex.rs | 8 - src/test/run-pass/unique/unique-ffi-symbols.rs | 16 - src/test/run-pass/unique/unique-fn-arg-move.rs | 11 - src/test/run-pass/unique/unique-fn-arg-mut.rs | 12 - src/test/run-pass/unique/unique-fn-arg.rs | 12 - src/test/run-pass/unique/unique-fn-ret.rs | 10 - src/test/run-pass/unique/unique-generic-assign.rs | 11 - src/test/run-pass/unique/unique-in-tag.rs | 22 - src/test/run-pass/unique/unique-in-vec-copy.rs | 16 - src/test/run-pass/unique/unique-in-vec.rs | 7 - src/test/run-pass/unique/unique-init.rs | 8 - src/test/run-pass/unique/unique-kinds.rs | 65 - src/test/run-pass/unique/unique-log.rs | 7 - src/test/run-pass/unique/unique-match-discrim.rs | 12 - src/test/run-pass/unique/unique-move-drop.rs | 11 - src/test/run-pass/unique/unique-move-temp.rs | 9 - src/test/run-pass/unique/unique-move.rs | 10 - src/test/run-pass/unique/unique-mutable.rs | 8 - src/test/run-pass/unique/unique-object-move.rs | 20 - src/test/run-pass/unique/unique-pat-2.rs | 18 - src/test/run-pass/unique/unique-pat-3.rs | 17 - src/test/run-pass/unique/unique-pat.rs | 15 - src/test/run-pass/unique/unique-rec.rs | 10 - src/test/run-pass/unique/unique-send-2.rs | 35 - src/test/run-pass/unique/unique-send.rs | 11 - src/test/run-pass/unique/unique-swap.rs | 12 - src/test/run-pass/unit.rs | 17 - src/test/run-pass/unnamed_argument_mode.rs | 14 - src/test/run-pass/unreachable-code-1.rs | 19 - src/test/run-pass/unreachable-code.rs | 28 - src/test/run-pass/unsafe-coercion.rs | 17 - .../run-pass/unsafe-fn-called-from-unsafe-blk.rs | 18 - .../run-pass/unsafe-fn-called-from-unsafe-fn.rs | 17 - src/test/run-pass/unsafe-pointer-assignability.rs | 11 - src/test/run-pass/unsized-locals/autoderef.rs | 49 - src/test/run-pass/unsized-locals/box-fnonce.rs | 10 - .../by-value-trait-object-safety-withdefault.rs | 23 - .../unsized-locals/reference-unsized-locals.rs | 9 - .../unsized-locals/simple-unsized-locals.rs | 8 - .../run-pass/unsized-locals/unsized-parameters.rs | 12 - src/test/run-pass/unsized-tuple-impls.rs | 21 - src/test/run-pass/unsized.rs | 25 - src/test/run-pass/unsized2.rs | 97 - src/test/run-pass/unused-move-capture.rs | 10 - src/test/run-pass/unused-move.rs | 15 - src/test/run-pass/unwind-resource.rs | 39 - src/test/run-pass/unwind-unique.rs | 16 - src/test/run-pass/use-crate-name-alias.rs | 7 - src/test/run-pass/use-import-export.rs | 12 - src/test/run-pass/use-keyword-2.rs | 23 - src/test/run-pass/use-mod.rs | 33 - src/test/run-pass/use-nested-groups.rs | 32 - src/test/run-pass/use.rs | 23 - src/test/run-pass/use_inline_dtor.rs | 10 - src/test/run-pass/using-target-feature-unstable.rs | 11 - src/test/run-pass/utf8-bom.rs | 6 - src/test/run-pass/utf8.rs | 50 - src/test/run-pass/utf8_chars.rs | 31 - src/test/run-pass/variadic-ffi.rs | 84 - .../variance-intersection-of-ref-and-opt-ref.rs | 25 - src/test/run-pass/variance-iterators-in-libcore.rs | 9 - src/test/run-pass/volatile-fat-ptr.rs | 15 - src/test/run-pass/wait-forked-but-failed-child.rs | 62 - src/test/run-pass/warn-ctypes-inhibit.rs | 17 - src/test/run-pass/weak-lang-item.rs | 15 - .../run-pass/weak-new-uninhabited-issue-48493.rs | 7 - src/test/run-pass/weird-exit-code.rs | 28 - src/test/run-pass/weird-exprs.rs | 180 - .../run-pass/wf-bound-region-in-object-type.rs | 22 - .../where-clauses/auxiliary/where_clauses_xc.rs | 19 - .../where-clause-bounds-inconsistency.rs | 23 - .../where-clause-early-bound-lifetimes.rs | 18 - .../where-clauses/where-clause-region-outlives.rs | 12 - .../where-clauses/where-clauses-cross-crate.rs | 13 - .../where-clauses/where-clauses-lifetimes.rs | 10 - .../run-pass/where-clauses/where-clauses-method.rs | 20 - .../where-clauses-unboxed-closures.rs | 17 - src/test/run-pass/where-clauses/where-clauses.rs | 27 - src/test/run-pass/wrapping-int-api.rs | 225 -- src/test/run-pass/write-fmt-errors.rs | 46 - src/test/run-pass/writealias.rs | 19 - src/test/run-pass/wrong-hashset-issue-42918.rs | 31 - src/test/run-pass/x86stdcall.rs | 36 - src/test/run-pass/x86stdcall2.rs | 33 - src/test/run-pass/yield.rs | 21 - src/test/run-pass/yield1.rs | 16 - src/test/run-pass/yield2.rs | 8 - src/test/run-pass/z-crate-attr.rs | 12 - .../zero-sized/zero-size-type-destructors.rs | 21 - .../zero-sized/zero-sized-binary-heap-push.rs | 20 - .../zero-sized/zero-sized-btreemap-insert.rs | 25 - .../zero-sized/zero-sized-linkedlist-push.rs | 29 - .../run-pass/zero-sized/zero-sized-tuple-struct.rs | 12 - .../zero-sized/zero-sized-vec-deque-push.rs | 32 - .../run-pass/zero-sized/zero-sized-vec-push.rs | 20 - src/test/ui-fulldeps/ast_stmt_expr_attr.rs | 304 ++ src/test/ui-fulldeps/auxiliary/issue-13560-1.rs | 3 + src/test/ui-fulldeps/auxiliary/issue-13560-2.rs | 3 + src/test/ui-fulldeps/auxiliary/issue-13560-3.rs | 6 + src/test/ui-fulldeps/auxiliary/issue-16822.rs | 20 + src/test/ui-fulldeps/auxiliary/issue-18502.rs | 21 + src/test/ui-fulldeps/auxiliary/issue-24106.rs | 13 + .../ui-fulldeps/auxiliary/issue-40001-plugin.rs | 57 + .../ui-fulldeps/auxiliary/linkage-visibility.rs | 37 + .../ui-fulldeps/auxiliary/lint-for-crate-rpass.rs | 74 + src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs | 20 + .../auxiliary/lto-syntax-extension-lib.rs | 5 + .../auxiliary/lto-syntax-extension-plugin.rs | 13 + src/test/ui-fulldeps/auxiliary/macro-crate-test.rs | 35 + .../auxiliary/outlive-expansion-phase.rs | 26 + src/test/ui-fulldeps/auxiliary/plugin-args.rs | 44 + src/test/ui-fulldeps/auxiliary/roman-numerals.rs | 70 + .../auxiliary/syntax-extension-with-dll-deps-1.rs | 7 + src/test/ui-fulldeps/compiler-calls.rs | 31 + src/test/ui-fulldeps/create-dir-all-bare.rs | 11 + .../ui-fulldeps/derive-no-std-not-supported.rs | 22 + .../deriving-encodable-decodable-box.rs | 24 + .../deriving-encodable-decodable-cell-refcell.rs | 37 + src/test/ui-fulldeps/deriving-global.rs | 35 + src/test/ui-fulldeps/deriving-hygiene.rs | 19 + src/test/ui-fulldeps/dropck_tarena_sound_drop.rs | 43 + src/test/ui-fulldeps/empty-struct-braces-derive.rs | 56 + src/test/ui-fulldeps/extern-mod-syntax.rs | 11 + src/test/ui-fulldeps/issue-11881.rs | 52 + src/test/ui-fulldeps/issue-13560.rs | 12 + src/test/ui-fulldeps/issue-14021.rs | 25 + src/test/ui-fulldeps/issue-15149.rs | 56 + src/test/ui-fulldeps/issue-15778-pass.rs | 15 + src/test/ui-fulldeps/issue-15924.rs | 27 + src/test/ui-fulldeps/issue-16822.rs | 22 + src/test/ui-fulldeps/issue-18502.rs | 8 + src/test/ui-fulldeps/issue-24106.rs | 8 + src/test/ui-fulldeps/issue-24972.rs | 29 + src/test/ui-fulldeps/issue-2804.rs | 70 + src/test/ui-fulldeps/issue-40001.rs | 9 + src/test/ui-fulldeps/issue-4016.rs | 20 + src/test/ui-fulldeps/issue-4036.rs | 17 + src/test/ui-fulldeps/linkage-visibility.rs | 13 + src/test/ui-fulldeps/llvm-pass-plugin.rs | 8 + src/test/ui-fulldeps/lto-syntax-extension.rs | 15 + .../ui-fulldeps/macro-crate-multi-decorator.rs | 49 + src/test/ui-fulldeps/mod_dir_path_canonicalized.rs | 29 + .../mod_dir_simple/compiletest-ignore-dir | 0 src/test/ui-fulldeps/mod_dir_simple/test.rs | 3 + src/test/ui-fulldeps/myriad-closures.rs | 39 + src/test/ui-fulldeps/newtype_index.rs | 22 + src/test/ui-fulldeps/outlive-expansion-phase.rs | 8 + src/test/ui-fulldeps/plugin-args-1.rs | 10 + src/test/ui-fulldeps/plugin-args-2.rs | 10 + src/test/ui-fulldeps/plugin-args-3.rs | 10 + src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 230 ++ src/test/ui-fulldeps/regions-mock-tcx.rs | 134 + src/test/ui-fulldeps/rename-directory.rs | 30 + src/test/ui-fulldeps/roman-numerals-macro.rs | 15 + src/test/ui-fulldeps/rustc_encodable_hygiene.rs | 24 + src/test/ui-fulldeps/stdio-from.rs | 69 + src/test/ui-fulldeps/switch-stdout.rs | 52 + src/test/ui-fulldeps/undef_mask.rs | 27 + src/test/ui/abi-sysv64-arg-passing.rs | 367 ++ src/test/ui/abi-sysv64-register-usage.rs | 96 + .../abi/issues/issue-62350-sysv-neg-reg-counts.rs | 46 + src/test/ui/abort-on-c-abi.rs | 38 + src/test/ui/alias-uninit-value.rs | 20 + src/test/ui/align-with-extern-c-fn.rs | 17 + src/test/ui/alignment-gep-tup-like-1.rs | 39 + src/test/ui/alloca-from-derived-tydesc.rs | 15 + src/test/ui/allocator-alloc-one.rs | 18 + .../ui/allocator/auxiliary/custom-as-global.rs | 16 + src/test/ui/allocator/auxiliary/custom.rs | 21 + src/test/ui/allocator/auxiliary/helper.rs | 9 + src/test/ui/allocator/custom-in-block.rs | 22 + src/test/ui/allocator/custom-in-submodule.rs | 26 + src/test/ui/allocator/custom.rs | 58 + src/test/ui/allocator/xcrate-use.rs | 35 + src/test/ui/allocator/xcrate-use2.rs | 47 + src/test/ui/anon-extern-mod.rs | 18 + src/test/ui/argument-passing.rs | 25 + src/test/ui/array-slice-vec/arr_cycle.rs | 31 + src/test/ui/array-slice-vec/array_const_index-1.rs | 12 + .../ui/array-slice-vec/box-of-array-of-drop-1.rs | 47 + .../ui/array-slice-vec/box-of-array-of-drop-2.rs | 47 + src/test/ui/array-slice-vec/cast-in-array-size.rs | 14 + .../ui/array-slice-vec/check-static-mut-slices.rs | 15 + src/test/ui/array-slice-vec/check-static-slice.rs | 36 + src/test/ui/array-slice-vec/copy-out-of-array-1.rs | 19 + src/test/ui/array-slice-vec/destructure-array-1.rs | 27 + src/test/ui/array-slice-vec/empty-mutable-vec.rs | 8 + src/test/ui/array-slice-vec/estr-slice.rs | 50 + src/test/ui/array-slice-vec/evec-slice.rs | 47 + src/test/ui/array-slice-vec/fixed_length_copy.rs | 9 + src/test/ui/array-slice-vec/huge-largest-array.rs | 14 + src/test/ui/array-slice-vec/ivec-pass-by-value.rs | 4 + ...mutability-inherits-through-fixed-length-vec.rs | 19 + src/test/ui/array-slice-vec/mutable-alias-vec.rs | 15 + src/test/ui/array-slice-vec/nested-vec-1.rs | 8 + src/test/ui/array-slice-vec/nested-vec-2.rs | 15 + src/test/ui/array-slice-vec/nested-vec-3.rs | 54 + .../array-slice-vec/new-style-fixed-length-vec.rs | 7 + .../ui/array-slice-vec/rcvr-borrowed-to-slice.rs | 33 + .../ui/array-slice-vec/repeated-vector-syntax.rs | 13 + src/test/ui/array-slice-vec/show-boxed-slice.rs | 8 + src/test/ui/array-slice-vec/slice-2.rs | 62 + .../array-slice-vec/slice-of-zero-size-elements.rs | 53 + src/test/ui/array-slice-vec/slice-panic-1.rs | 26 + src/test/ui/array-slice-vec/slice-panic-2.rs | 30 + src/test/ui/array-slice-vec/slice.rs | 81 + src/test/ui/array-slice-vec/slice_binary_search.rs | 21 + .../ui/array-slice-vec/variance-vec-covariant.rs | 20 + src/test/ui/array-slice-vec/vec-concat.rs | 14 + src/test/ui/array-slice-vec/vec-dst.rs | 26 + src/test/ui/array-slice-vec/vec-fixed-length.rs | 24 + src/test/ui/array-slice-vec/vec-growth.rs | 16 + src/test/ui/array-slice-vec/vec-late-init.rs | 9 + src/test/ui/array-slice-vec/vec-macro-no-std.rs | 27 + src/test/ui/array-slice-vec/vec-macro-repeat.rs | 15 + .../ui/array-slice-vec/vec-macro-rvalue-scope.rs | 11 + .../ui/array-slice-vec/vec-macro-with-brackets.rs | 16 + .../vec-macro-with-trailing-comma.rs | 8 + .../ui/array-slice-vec/vec-matching-autoslice.rs | 23 + src/test/ui/array-slice-vec/vec-matching-fixed.rs | 32 + src/test/ui/array-slice-vec/vec-matching-fold.rs | 48 + .../vec-matching-legal-tail-element-borrow.rs | 16 + src/test/ui/array-slice-vec/vec-matching.rs | 159 + src/test/ui/array-slice-vec/vec-push.rs | 3 + .../ui/array-slice-vec/vec-repeat-with-cast.rs | 5 + src/test/ui/array-slice-vec/vec-slice-drop.rs | 31 + src/test/ui/array-slice-vec/vec-slice.rs | 9 + src/test/ui/array-slice-vec/vec-tail-matching.rs | 36 + src/test/ui/array-slice-vec/vec-to_str.rs | 12 + src/test/ui/array-slice-vec/vec.rs | 15 + src/test/ui/array-slice-vec/vec_cycle.rs | 39 + src/test/ui/array-slice-vec/vec_cycle_wrapped.rs | 50 + src/test/ui/array-slice-vec/vector-no-ann-2.rs | 7 + src/test/ui/artificial-block.rs | 5 + src/test/ui/as-precedence.rs | 9 + src/test/ui/asm-concat-src.rs | 9 + src/test/ui/asm-in-moved.rs | 31 + src/test/ui/asm-in-out-operand.rs | 56 + src/test/ui/asm-indirect-memory.rs | 43 + src/test/ui/asm-out-assign.rs | 25 + src/test/ui/assert-eq-trailing-comma.rs | 5 + src/test/ui/assert-escape.rs | 5 + src/test/ui/assert-ne-trailing-comma.rs | 5 + src/test/ui/assign-assign.rs | 30 + src/test/ui/assoc-oddities-3.rs | 13 + .../associated-const-const-eval.rs | 20 + .../associated-const-cross-crate-const-eval.rs | 28 + .../associated-const-cross-crate-defaults.rs | 22 + .../associated-const-cross-crate.rs | 17 + .../associated-const-in-global-const.rs | 13 + .../associated-const-inherent-impl.rs | 11 + .../associated-const-marks-live-code.rs | 15 + .../associated-const-match-patterns.rs | 68 + .../associated-const-outer-ty-refs.rs | 10 + .../associated-const-overwrite-default.rs | 13 + .../associated-const-public-impl.rs | 16 + .../associated-const-range-match-patterns.rs | 40 + .../associated-const-resolution-order.rs | 25 + .../associated-const-self-type.rs | 13 + .../associated-const-type-parameters.rs | 44 + .../associated-const-ufcs-infer-trait.rs | 13 + .../associated-const-use-default.rs | 11 + .../associated-const-use-impl-of-same-trait.rs | 25 + src/test/ui/associated-consts/associated-const.rs | 13 + .../auxiliary/associated-const-cc-lib.rs | 34 + .../ui/associated-consts/auxiliary/empty-struct.rs | 9 + src/test/ui/associated-item-long-paths.rs | 47 + .../ui/associated-types/associated-types-basic.rs | 14 + .../associated-types-binding-in-trait.rs | 36 + .../associated-types-binding-in-where-clause.rs | 38 + .../ui/associated-types/associated-types-bound.rs | 43 + .../ui/associated-types/associated-types-cc.rs | 18 + .../associated-types-conditional-dispatch.rs | 66 + .../associated-types-constant-type.rs | 31 + .../associated-types-doubleendediterator-object.rs | 20 + ...sociated-types-duplicate-binding-in-env-hrtb.rs | 17 + .../associated-types-duplicate-binding-in-env.rs | 21 + .../associated-types-enum-field-named.rs | 35 + .../associated-types-enum-field-numbered.rs | 35 + .../ui/associated-types/associated-types-eq-obj.rs | 25 + .../associated-types-from-supertrait.rs | 8 + .../associated-types-impl-redirect.rs | 51 + .../associated-types-in-bound-type-arg.rs | 17 + .../associated-types-in-default-method.rs | 27 + .../ui/associated-types/associated-types-in-fn.rs | 28 + .../associated-types-in-impl-generics.rs | 36 + .../associated-types-in-inherent-method.rs | 30 + .../associated-types-issue-20220.rs | 28 + .../associated-types-issue-20371.rs | 9 + .../associated-types-issue-21212.rs | 22 + .../associated-types-iterator-binding.rs | 19 + .../ui/associated-types/associated-types-method.rs | 27 + .../associated-types-nested-projections.rs | 44 + ...associated-types-normalize-in-bounds-binding.rs | 38 + .../associated-types-normalize-in-bounds-ufcs.rs | 35 + .../associated-types-normalize-in-bounds.rs | 35 + .../associated-types-normalize-unifield-struct.rs | 24 + ...s-project-from-type-param-via-bound-in-where.rs | 98 + ...ciated-types-projection-bound-in-supertraits.rs | 23 + ...ted-types-projection-from-known-type-in-impl.rs | 38 + .../associated-types-projection-in-object-type.rs | 40 + .../associated-types-projection-in-supertrait.rs | 45 + .../associated-types-projection-in-where-clause.rs | 31 + ...sociated-types-projection-to-unrelated-trait.rs | 35 + ...alified-path-with-trait-with-type-parameters.rs | 9 + .../associated-types-ref-from-struct.rs | 55 + .../associated-types-ref-in-struct-literal.rs | 23 + .../associated-types-region-erasure-issue-20582.rs | 21 + .../associated-types-resolve-lifetime.rs | 15 + .../ui/associated-types/associated-types-return.rs | 46 + .../ui/associated-types/associated-types-simple.rs | 24 + .../ui/associated-types/associated-types-stream.rs | 39 + .../associated-types-struct-field-named.rs | 35 + .../associated-types-struct-field-numbered.rs | 32 + .../associated-types-sugar-path.rs | 41 + ...associated-types-where-clause-impl-ambiguity.rs | 46 + .../auxiliary/associated-types-cc-lib.rs | 16 + src/test/ui/atomic-access-bool.rs | 24 + src/test/ui/atomic-alignment.rs | 38 + src/test/ui/atomic-compare_exchange.rs | 31 + src/test/ui/atomic-print.rs | 46 + src/test/ui/attr-main-2.rs | 11 + src/test/ui/attr-main.rs | 8 + src/test/ui/attr-shebang.rs | 6 + src/test/ui/attr-start.rs | 9 + src/test/ui/attr.rs | 8 + .../ui/augmented-assignments-feature-gate-cross.rs | 11 + src/test/ui/augmented-assignments-feature-gate.rs | 15 + src/test/ui/auto-instantiate.rs | 13 + src/test/ui/auto-is-contextual.rs | 18 + src/test/ui/autobind.rs | 12 + .../autoref-autoderef/auto-ref-bounded-ty-param.rs | 29 + .../ui/autoref-autoderef/auto-ref-sliceable.rs | 19 + src/test/ui/autoref-autoderef/auto-ref.rs | 19 + .../autoderef-and-borrow-method-receiver.rs | 18 + .../autoref-autoderef/autoderef-method-on-trait.rs | 16 + .../autoref-autoderef/autoderef-method-priority.rs | 20 + .../autoderef-method-twice-but-not-thrice.rs | 16 + .../ui/autoref-autoderef/autoderef-method-twice.rs | 16 + src/test/ui/autoref-autoderef/autoderef-method.rs | 16 + src/test/ui/autoref-autoderef/autoderef-privacy.rs | 51 + .../autoref-intermediate-types-issue-3585.rs | 23 + .../ui/auxiliary/anon-extern-mod-cross-crate-1.rs | 9 + src/test/ui/auxiliary/augmented_assignments.rs | 8 + .../blind-item-mixed-crate-use-item-foo.rs | 3 + .../blind-item-mixed-crate-use-item-foo2.rs | 3 + .../check_static_recursion_foreign_helper.rs | 11 + src/test/ui/auxiliary/cond_plugin.rs | 38 + .../auxiliary/crate-method-reexport-grrrrrrr2.rs | 31 + src/test/ui/auxiliary/debuginfo-lto-aux.rs | 29 + src/test/ui/auxiliary/edition-kw-macro-2015.rs | 26 + src/test/ui/auxiliary/edition-kw-macro-2018.rs | 26 + src/test/ui/auxiliary/foreign_lib.rs | 38 + src/test/ui/auxiliary/hello_macro.rs | 21 + src/test/ui/auxiliary/impl_privacy_xc_1.rs | 9 + src/test/ui/auxiliary/impl_privacy_xc_2.rs | 13 + src/test/ui/auxiliary/inline_dtor.rs | 8 + src/test/ui/auxiliary/inner_static.rs | 51 + src/test/ui/auxiliary/kinds_in_metadata.rs | 8 + .../auxiliary/link-cfg-works-transitive-dylib.rs | 4 + .../ui/auxiliary/link-cfg-works-transitive-rlib.rs | 7 + src/test/ui/auxiliary/linkage1.rs | 4 + src/test/ui/auxiliary/llvm_pr32379.rs | 5 + src/test/ui/auxiliary/msvc-data-only-lib.rs | 5 + src/test/ui/auxiliary/nested_item.rs | 30 + src/test/ui/auxiliary/proc_macro_def.rs | 35 + .../ui/auxiliary/reachable-unnameable-items.rs | 106 + .../ui/auxiliary/reexport-should-still-link.rs | 5 + src/test/ui/auxiliary/rmeta-rmeta.rs | 9 + src/test/ui/auxiliary/svh-a-base.rs | 25 + src/test/ui/auxiliary/svh-b.rs | 13 + .../ui/auxiliary/trait_superkinds_in_metadata.rs | 8 + src/test/ui/auxiliary/typeid-intrinsic-aux1.rs | 29 + src/test/ui/auxiliary/typeid-intrinsic-aux2.rs | 29 + .../ui/auxiliary/using-target-feature-unstable.rs | 5 + src/test/ui/backtrace-debuginfo-aux.rs | 14 + src/test/ui/backtrace-debuginfo.rs | 180 + src/test/ui/backtrace.rs | 125 + src/test/ui/bare-fn-implements-fn-mut.rs | 27 + src/test/ui/bare-static-string.rs | 6 + src/test/ui/bench/issue-32062.rs | 50 + src/test/ui/big-literals.rs | 17 + src/test/ui/binary-minus-without-space.rs | 8 + src/test/ui/bind-by-move.rs | 13 + .../ui/binding/bind-field-short-with-modifiers.rs | 26 + src/test/ui/binding/borrowed-ptr-pattern-2.rs | 13 + src/test/ui/binding/borrowed-ptr-pattern-3.rs | 13 + .../ui/binding/borrowed-ptr-pattern-infallible.rs | 8 + src/test/ui/binding/borrowed-ptr-pattern-option.rs | 15 + src/test/ui/binding/borrowed-ptr-pattern.rs | 12 + src/test/ui/binding/empty-types-in-patterns.rs | 58 + .../ui/binding/exhaustive-bool-match-sanity.rs | 22 + src/test/ui/binding/expr-match-generic-unique1.rs | 19 + src/test/ui/binding/expr-match-generic-unique2.rs | 17 + src/test/ui/binding/expr-match-generic.rs | 29 + src/test/ui/binding/expr-match-panic-all.rs | 14 + src/test/ui/binding/expr-match-panic.rs | 14 + src/test/ui/binding/expr-match-unique.rs | 10 + src/test/ui/binding/expr-match.rs | 45 + src/test/ui/binding/fat-arrow-match.rs | 17 + .../fn-arg-incomplete-pattern-drop-order.rs | 69 + src/test/ui/binding/fn-pattern-expected-type-2.rs | 8 + src/test/ui/binding/fn-pattern-expected-type.rs | 9 + src/test/ui/binding/func-arg-incomplete-pattern.rs | 24 + src/test/ui/binding/func-arg-ref-pattern.rs | 28 + src/test/ui/binding/func-arg-wild-pattern.rs | 12 + src/test/ui/binding/if-let.rs | 60 + .../ui/binding/inconsistent-lifetime-mismatch.rs | 15 + .../ui/binding/inferred-suffix-in-pattern-range.rs | 24 + src/test/ui/binding/irrefutable-slice-patterns.rs | 15 + src/test/ui/binding/let-assignability.rs | 12 + src/test/ui/binding/let-destruct-ref.rs | 7 + src/test/ui/binding/let-var-hygiene.rs | 11 + src/test/ui/binding/match-arm-statics.rs | 164 + src/test/ui/binding/match-beginning-vert.rs | 19 + src/test/ui/binding/match-borrowed_str.rs | 48 + src/test/ui/binding/match-bot-2.rs | 6 + src/test/ui/binding/match-bot.rs | 7 + src/test/ui/binding/match-byte-array-patterns.rs | 45 + src/test/ui/binding/match-enum-struct-0.rs | 17 + src/test/ui/binding/match-enum-struct-1.rs | 19 + src/test/ui/binding/match-implicit-copy-unique.rs | 17 + src/test/ui/binding/match-in-macro.rs | 17 + src/test/ui/binding/match-join.rs | 20 + src/test/ui/binding/match-larger-const.rs | 12 + src/test/ui/binding/match-naked-record-expr.rs | 12 + src/test/ui/binding/match-naked-record.rs | 13 + src/test/ui/binding/match-path.rs | 14 + src/test/ui/binding/match-pattern-bindings.rs | 21 + src/test/ui/binding/match-pattern-lit.rs | 15 + .../ui/binding/match-pattern-no-type-params.rs | 14 + src/test/ui/binding/match-pattern-simple.rs | 9 + src/test/ui/binding/match-phi.rs | 19 + src/test/ui/binding/match-pipe-binding.rs | 60 + src/test/ui/binding/match-range-infer.rs | 17 + src/test/ui/binding/match-range-static.rs | 13 + src/test/ui/binding/match-range.rs | 51 + src/test/ui/binding/match-reassign.rs | 21 + .../ui/binding/match-ref-binding-in-guard-3256.rs | 13 + .../ui/binding/match-ref-binding-mut-option.rs | 10 + src/test/ui/binding/match-ref-binding-mut.rs | 18 + src/test/ui/binding/match-ref-binding.rs | 12 + src/test/ui/binding/match-ref-unsized.rs | 11 + src/test/ui/binding/match-str.rs | 25 + src/test/ui/binding/match-struct-0.rs | 21 + src/test/ui/binding/match-tag.rs | 30 + src/test/ui/binding/match-unique-bind.rs | 12 + src/test/ui/binding/match-unsized.rs | 9 + .../binding/match-value-binding-in-guard-3291.rs | 19 + src/test/ui/binding/match-var-hygiene.rs | 11 + src/test/ui/binding/match-vec-alternatives.rs | 81 + src/test/ui/binding/match-vec-rvalue.rs | 15 + src/test/ui/binding/match-with-ret-arm.rs | 12 + src/test/ui/binding/multi-let.rs | 7 + src/test/ui/binding/mut-in-ident-patterns.rs | 76 + src/test/ui/binding/nested-exhaustive-match.rs | 14 + src/test/ui/binding/nested-matchs.rs | 16 + src/test/ui/binding/nested-pattern.rs | 16 + src/test/ui/binding/nil-pattern.rs | 4 + src/test/ui/binding/nullary-or-pattern.rs | 13 + src/test/ui/binding/optional_comma_in_match_arm.rs | 40 + src/test/ui/binding/or-pattern.rs | 14 + src/test/ui/binding/order-drop-with-match.rs | 57 + src/test/ui/binding/pat-ranges.rs | 20 + src/test/ui/binding/pat-tuple-1.rs | 93 + src/test/ui/binding/pat-tuple-2.rs | 23 + src/test/ui/binding/pat-tuple-3.rs | 29 + src/test/ui/binding/pat-tuple-4.rs | 57 + src/test/ui/binding/pat-tuple-5.rs | 29 + src/test/ui/binding/pat-tuple-6.rs | 45 + src/test/ui/binding/pat-tuple-7.rs | 8 + .../ui/binding/pattern-bound-var-in-for-each.rs | 20 + src/test/ui/binding/pattern-in-closure.rs | 14 + .../binding/range-inclusive-pattern-precedence.rs | 23 + src/test/ui/binding/simple-generic-match.rs | 8 + src/test/ui/binding/use-uninit-match.rs | 17 + src/test/ui/binding/use-uninit-match2.rs | 18 + src/test/ui/binding/zero_sized_subslice_match.rs | 12 + src/test/ui/binops-issue-22743.rs | 24 + src/test/ui/binops.rs | 89 + src/test/ui/bitwise.rs | 34 + src/test/ui/blind-item-local-shadow.rs | 13 + src/test/ui/blind-item-mixed-crate-use-item.rs | 26 + src/test/ui/blind-item-mixed-use-item.rs | 20 + src/test/ui/block-arg-call-as.rs | 12 + src/test/ui/block-arg.rs | 11 + src/test/ui/block-explicit-types.rs | 6 + src/test/ui/block-expr-precedence.rs | 61 + src/test/ui/block-fn-coerce.rs | 10 + src/test/ui/block-iter-1.rs | 15 + src/test/ui/block-iter-2.rs | 15 + src/test/ui/bool-not.rs | 6 + src/test/ui/bool.rs | 72 + src/test/ui/borrow-by-val-method-receiver.rs | 14 + .../ui/borrowck/borrowck-assign-to-subfield.rs | 23 + .../borrowck/borrowck-assignment-to-static-mut.rs | 11 + src/test/ui/borrowck/borrowck-binding-mutbl.rs | 16 + .../ui/borrowck/borrowck-borrow-from-expr-block.rs | 18 + .../borrowck-borrow-of-mut-base-ptr-safe.rs | 21 + src/test/ui/borrowck/borrowck-closures-two-imm.rs | 41 + src/test/ui/borrowck/borrowck-fixed-length-vecs.rs | 7 + src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs | 28 + src/test/ui/borrowck/borrowck-lend-args.rs | 21 + .../borrowck-macro-interaction-issue-6304.rs | 38 + .../ui/borrowck/borrowck-move-by-capture-ok.rs | 8 + .../borrowck-multiple-borrows-interior-boxes.rs | 20 + src/test/ui/borrowck/borrowck-mut-uniq.rs | 33 + .../ui/borrowck/borrowck-mut-vec-as-imm-slice.rs | 16 + src/test/ui/borrowck/borrowck-pat-enum.rs | 39 + .../borrowck/borrowck-pat-reassign-no-binding.rs | 14 + src/test/ui/borrowck/borrowck-rvalues-mutable.rs | 34 + .../borrowck/borrowck-scope-of-deref-issue-4666.rs | 42 + src/test/ui/borrowck/borrowck-static-item-in-fn.rs | 9 + src/test/ui/borrowck/borrowck-trait-lifetime.rs | 18 + src/test/ui/borrowck/borrowck-uniq-via-ref.rs | 49 + src/test/ui/borrowck/borrowck-univariant-enum.rs | 25 + .../borrowck-unsafe-static-mutable-borrows.rs | 20 + src/test/ui/borrowck/borrowck-unused-mut-locals.rs | 46 + src/test/ui/borrowck/issue-62007-assign-box.rs | 27 + src/test/ui/borrowck/issue-62007-assign-field.rs | 26 + src/test/ui/borrowck/two-phase-baseline.rs | 9 + src/test/ui/borrowck/two-phase-bin-ops.rs | 35 + ...o-phase-control-flow-split-before-activation.rs | 15 + src/test/ui/box-new.rs | 6 + src/test/ui/bug-7183-generics.rs | 36 + src/test/ui/bug-7295.rs | 14 + src/test/ui/builtin-clone-unwind.rs | 61 + src/test/ui/builtin-clone.rs | 45 + .../builtin-superkinds-capabilities-transitive.rs | 25 + src/test/ui/builtin-superkinds-capabilities-xc.rs | 27 + src/test/ui/builtin-superkinds-capabilities.rs | 21 + src/test/ui/builtin-superkinds-in-metadata.rs | 23 + src/test/ui/builtin-superkinds-phantom-typaram.rs | 18 + src/test/ui/builtin-superkinds-simple.rs | 10 + src/test/ui/builtin-superkinds-typaram.rs | 11 + src/test/ui/byte-literals.rs | 67 + src/test/ui/c-stack-as-value.rs | 18 + src/test/ui/c-stack-returning-int64.rs | 34 + src/test/ui/cabi-int-widening.rs | 15 + src/test/ui/can-copy-pod.rs | 16 + .../ui/cancel-clean-via-immediate-rvalue-ref.rs | 12 + src/test/ui/cast-does-fallback.rs | 12 + src/test/ui/cast-region-to-uint.rs | 6 + src/test/ui/cast-rfc0401-vtable-kinds.rs | 62 + src/test/ui/cast-rfc0401.rs | 173 + src/test/ui/cast-to-infer-ty.rs | 8 + src/test/ui/cast.rs | 21 + src/test/ui/catch-unwind-bang.rs | 10 + src/test/ui/cell-does-not-clone.rs | 26 + src/test/ui/cfg/auxiliary/cfg_inner_static.rs | 7 + .../auxiliary/crate-attributes-using-cfg_attr.rs | 6 + src/test/ui/cfg/cfg-attr-cfg.rs | 8 + src/test/ui/cfg/cfg-attr-crate.rs | 8 + src/test/ui/cfg/cfg-family.rs | 13 + src/test/ui/cfg/cfg-in-crate-1.rs | 5 + src/test/ui/cfg/cfg-macros-foo.rs | 26 + src/test/ui/cfg/cfg-macros-notfoo.rs | 26 + src/test/ui/cfg/cfg-match-arm.rs | 20 + src/test/ui/cfg/cfg-target-family.rs | 14 + src/test/ui/cfg/cfg-target-vendor.rs | 8 + src/test/ui/cfg/cfg_attr.rs | 50 + src/test/ui/cfg/cfg_inner_static.rs | 10 + src/test/ui/cfg/cfg_stmt_expr.rs | 92 + src/test/ui/cfg/cfgs-on-items.rs | 29 + src/test/ui/cfg/conditional-compile-arch.rs | 38 + src/test/ui/cfg/conditional-compile.rs | 149 + src/test/ui/cfg/crate-attributes-using-cfg_attr.rs | 6 + src/test/ui/chalkify/builtin-copy-clone.rs | 44 + src/test/ui/chalkify/inherent_impl.rs | 42 + src/test/ui/chalkify/projection.rs | 25 + src/test/ui/chalkify/super_trait.rs | 19 + src/test/ui/chalkify/trait_implied_bound.rs | 18 + src/test/ui/chalkify/type_implied_bound.rs | 29 + src/test/ui/char.rs | 13 + src/test/ui/char_unicode.rs | 12 + src/test/ui/check-static-recursion-foreign.rs | 26 + src/test/ui/check_const-feature-gated.rs | 7 + src/test/ui/child-outlives-parent.rs | 13 + src/test/ui/cleanup-arm-conditional.rs | 39 + src/test/ui/cleanup-rvalue-during-if-and-while.rs | 43 + src/test/ui/cleanup-rvalue-for-scope.rs | 63 + src/test/ui/cleanup-rvalue-scopes.rs | 131 + .../cleanup-rvalue-temp-during-incomplete-alloc.rs | 48 + src/test/ui/cleanup-shortcircuit.rs | 22 + src/test/ui/clone-with-exterior.rs | 22 + src/test/ui/close-over-big-then-small-data.rs | 41 + src/test/ui/cmp-default.rs | 73 + src/test/ui/codegen-object-shim.rs | 6 + src/test/ui/coerce/coerce-expect-unsized.rs | 43 + src/test/ui/coerce/coerce-overloaded-autoderef.rs | 67 + src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs | 17 + src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs | 18 + src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs | 19 + src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs | 16 + src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs | 25 + src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs | 27 + src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs | 18 + src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs | 14 + src/test/ui/coerce/coerce-unify-return.rs | 19 + src/test/ui/coerce/coerce-unify.rs | 68 + src/test/ui/coerce/coerce-unsize-subtype.rs | 40 + .../auxiliary/re_rebalance_coherence_lib-rpass.rs | 31 + src/test/ui/coherence/coherence-bigint-int.rs | 16 + src/test/ui/coherence/coherence-bigint-vecint.rs | 16 + src/test/ui/coherence/coherence-blanket.rs | 19 + .../coherence/coherence-covered-type-parameter.rs | 17 + src/test/ui/coherence/coherence-impl-in-fn.rs | 17 + .../coherence/coherence-iterator-vec-any-elem.rs | 17 + src/test/ui/coherence/coherence-iterator-vec.rs | 17 + .../ui/coherence/coherence-multidispatch-tuple.rs | 27 + .../ui/coherence/coherence-rfc447-constrained.rs | 25 + src/test/ui/coherence/coherence-where-clause.rs | 41 + src/test/ui/coherence/coherence_copy_like.rs | 22 + ...ce-coherence-default-generic-associated-type.rs | 27 + src/test/ui/collections-const-new.rs | 15 + src/test/ui/command-exec.rs | 104 + src/test/ui/command-pre-exec.rs | 118 + src/test/ui/command-uid-gid.rs | 32 + src/test/ui/complex.rs | 38 + src/test/ui/consts/assoc-const.rs | 21 + .../auxiliary/anon-extern-mod-cross-crate-1.rs | 9 + src/test/ui/consts/auxiliary/cci_borrow_lib.rs | 3 + src/test/ui/consts/auxiliary/cci_const.rs | 6 + src/test/ui/consts/auxiliary/cci_const_block.rs | 6 + src/test/ui/consts/bswap-const.rs | 15 + .../ui/consts/chained-constants-stackoverflow.rs | 356 ++ src/test/ui/consts/const-adt-align-mismatch.rs | 22 + src/test/ui/consts/const-autoderef.rs | 11 + src/test/ui/consts/const-big-enum.rs | 30 + src/test/ui/consts/const-binops.rs | 126 + src/test/ui/consts/const-bitshift-rhs-inference.rs | 24 + src/test/ui/consts/const-block-cross-crate-fn.rs | 9 + .../ui/consts/const-block-item-macro-codegen.rs | 40 + src/test/ui/consts/const-block-item.rs | 41 + .../ui/consts/const-block-non-item-statement-3.rs | 8 + src/test/ui/consts/const-block.rs | 45 + src/test/ui/consts/const-bound.rs | 20 + src/test/ui/consts/const-byte-str-cast.rs | 9 + src/test/ui/consts/const-cast-ptr-int.rs | 16 + src/test/ui/consts/const-cast.rs | 16 + src/test/ui/consts/const-const.rs | 9 + src/test/ui/consts/const-contents.rs | 19 + src/test/ui/consts/const-cross-crate-const.rs | 16 + src/test/ui/consts/const-cross-crate-extern.rs | 11 + src/test/ui/consts/const-deref.rs | 8 + src/test/ui/consts/const-endianess.rs | 21 + src/test/ui/consts/const-enum-byref-self.rs | 18 + src/test/ui/consts/const-enum-byref.rs | 16 + src/test/ui/consts/const-enum-cast.rs | 26 + src/test/ui/consts/const-enum-ptr.rs | 12 + src/test/ui/consts/const-enum-struct.rs | 12 + src/test/ui/consts/const-enum-struct2.rs | 12 + src/test/ui/consts/const-enum-structlike.rs | 16 + src/test/ui/consts/const-enum-tuple.rs | 11 + src/test/ui/consts/const-enum-tuple2.rs | 11 + src/test/ui/consts/const-enum-tuplestruct.rs | 12 + src/test/ui/consts/const-enum-tuplestruct2.rs | 12 + src/test/ui/consts/const-enum-vec-index.rs | 30 + src/test/ui/consts/const-enum-vec-ptr.rs | 15 + src/test/ui/consts/const-enum-vector.rs | 15 + .../ui/consts/const-expr-in-fixed-length-vec.rs | 12 + src/test/ui/consts/const-expr-in-vec-repeat.rs | 11 + src/test/ui/consts/const-extern-function.rs | 16 + src/test/ui/consts/const-fields-and-indexing.rs | 28 + src/test/ui/consts/const-fn-const-eval.rs | 10 + src/test/ui/consts/const-fn-feature-flags.rs | 13 + src/test/ui/consts/const-fn-method.rs | 16 + src/test/ui/consts/const-fn-nested.rs | 12 + src/test/ui/consts/const-fn-stability-calls.rs | 27 + src/test/ui/consts/const-fn-type-name.rs | 37 + src/test/ui/consts/const-fn-val.rs | 15 + src/test/ui/consts/const-fn.rs | 42 + src/test/ui/consts/const-index-feature-gate.rs | 7 + src/test/ui/consts/const-int-saturating-arith.rs | 35 + src/test/ui/consts/const-meth-pattern.rs | 18 + src/test/ui/consts/const-needs_drop.rs | 29 + src/test/ui/consts/const-negation.rs | 35 + src/test/ui/consts/const-negative.rs | 9 + src/test/ui/consts/const-nullary-enum.rs | 23 + .../ui/consts/const-nullary-univariant-enum.rs | 15 + src/test/ui/consts/const-pattern-variant.rs | 29 + src/test/ui/consts/const-rec-and-tup.rs | 20 + src/test/ui/consts/const-region-ptrs-noncopy.rs | 12 + src/test/ui/consts/const-region-ptrs.rs | 15 + src/test/ui/consts/const-repeated-values.rs | 10 + src/test/ui/consts/const-size_of-align_of.rs | 51 + src/test/ui/consts/const-str-ptr.rs | 17 + src/test/ui/consts/const-struct-offsets.rs | 18 + src/test/ui/consts/const-struct.rs | 32 + src/test/ui/consts/const-trait-to-trait.rs | 24 + src/test/ui/consts/const-tuple-struct.rs | 14 + src/test/ui/consts/const-unit-struct.rs | 12 + src/test/ui/consts/const-unsafe-fn.rs | 21 + src/test/ui/consts/const-vec-of-fns.rs | 25 + src/test/ui/consts/const-vec-syntax.rs | 9 + src/test/ui/consts/const-vecs-and-slices.rs | 23 + src/test/ui/consts/const.rs | 6 + src/test/ui/consts/consts-in-patterns.rs | 18 + src/test/ui/consts/deref_in_pattern.rs | 12 + src/test/ui/consts/ice-48279.rs | 26 + src/test/ui/consts/issue-37550.rs | 12 + src/test/ui/consts/issue-broken-mir.rs | 10 + src/test/ui/consts/locals-in-const-fn.rs | 35 + src/test/ui/consts/match-const-fn-structs.rs | 22 + src/test/ui/consts/mozjs-error.rs | 31 + src/test/ui/consts/non-scalar-cast.rs | 9 + src/test/ui/consts/promotion.rs | 17 + src/test/ui/consts/references.rs | 27 + src/test/ui/consts/repeat_match.rs | 12 + src/test/ui/consts/return-in-const-fn.rs | 10 + src/test/ui/consts/signed_enum_discr.rs | 19 + src/test/ui/consts/transmute-const.rs | 14 + src/test/ui/consts/tuple-struct-constructors.rs | 10 + src/test/ui/core-run-destroy.rs | 87 + src/test/ui/crate-leading-sep.rs | 7 + src/test/ui/crate-method-reexport-grrrrrrr.rs | 21 + src/test/ui/crate-name-attr-used.rs | 8 + .../cross-crate/anon-extern-mod-cross-crate-2.rs | 14 + .../auxiliary/anon-extern-mod-cross-crate-1.rs | 9 + .../auxiliary/anon_trait_static_method_lib.rs | 9 + .../ui/cross-crate/auxiliary/cci_borrow_lib.rs | 3 + .../ui/cross-crate/auxiliary/cci_capture_clause.rs | 10 + src/test/ui/cross-crate/auxiliary/cci_const.rs | 6 + src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs | 16 + src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs | 11 + .../ui/cross-crate/auxiliary/cci_nested_lib.rs | 52 + .../ui/cross-crate/auxiliary/cci_no_inline_lib.rs | 12 + .../auxiliary/moves_based_on_type_lib.rs | 17 + .../ui/cross-crate/auxiliary/newtype_struct_xc.rs | 3 + .../ui/cross-crate/auxiliary/pub_static_array.rs | 1 + .../auxiliary/reexported_static_methods.rs | 43 + .../auxiliary/xcrate-trait-lifetime-param.rs | 3 + .../auxiliary/xcrate_address_insignificant.rs | 8 + .../auxiliary/xcrate_associated_type_defaults.rs | 12 + .../auxiliary/xcrate_generic_fn_nested_return.rs | 16 + .../auxiliary/xcrate_static_addresses.rs | 17 + .../ui/cross-crate/auxiliary/xcrate_unit_struct.rs | 28 + src/test/ui/cross-crate/cci_borrow.rs | 14 + src/test/ui/cross-crate/cci_capture_clause.rs | 14 + src/test/ui/cross-crate/cci_impl_exe.rs | 18 + src/test/ui/cross-crate/cci_iter_exe.rs | 13 + src/test/ui/cross-crate/cci_nested_exe.rs | 20 + src/test/ui/cross-crate/cci_no_inline_exe.rs | 23 + src/test/ui/cross-crate/cross-crate-const-pat.rs | 14 + .../cross-crate/cross-crate-newtype-struct-pat.rs | 12 + .../cross-crate/moves-based-on-type-cross-crate.rs | 11 + .../reexported-static-methods-cross-crate.rs | 16 + .../ui/cross-crate/static-array-across-crate.rs | 13 + .../ui/cross-crate/xcrate-address-insignificant.rs | 9 + .../cross-crate/xcrate-associated-type-defaults.rs | 29 + src/test/ui/cross-crate/xcrate-static-addresses.rs | 13 + .../ui/cross-crate/xcrate-trait-lifetime-param.rs | 19 + src/test/ui/cross-crate/xcrate-unit-struct.rs | 30 + .../cross-crate/xcrate_generic_fn_nested_return.rs | 8 + src/test/ui/crt-static-off-works.rs | 10 + src/test/ui/crt-static-on-works.rs | 9 + src/test/ui/cycle-generic-bound.rs | 11 + src/test/ui/dead-code-alias-in-pat.rs | 10 + src/test/ui/dead-code-leading-underscore.rs | 31 + src/test/ui/debuginfo-lto.rs | 24 + src/test/ui/deep.rs | 8 + src/test/ui/default-alloc-error-hook.rs | 20 + src/test/ui/default-associated-types.rs | 23 + src/test/ui/default-method-parsing.rs | 8 + src/test/ui/default-method-simple.rs | 26 + src/test/ui/defaults-well-formedness.rs | 27 + src/test/ui/deprecation-in-force-unstable.rs | 5 + src/test/ui/deref-lval.rs | 11 + src/test/ui/deref-mut-on-ref.rs | 15 + src/test/ui/deref-on-ref.rs | 19 + src/test/ui/deref-rc.rs | 8 + src/test/ui/deref.rs | 9 + src/test/ui/deriving/auxiliary/derive-no-std.rs | 29 + src/test/ui/deriving/derive-no-std.rs | 12 + .../ui/deriving/derive-partialord-correctness.rs | 9 + src/test/ui/deriving/deriving-associated-types.rs | 199 ++ src/test/ui/deriving/deriving-bounds.rs | 5 + src/test/ui/deriving/deriving-clone-array.rs | 10 + src/test/ui/deriving/deriving-clone-enum.rs | 14 + .../ui/deriving/deriving-clone-generic-enum.rs | 14 + .../ui/deriving/deriving-clone-generic-struct.rs | 13 + .../deriving-clone-generic-tuple-struct.rs | 9 + src/test/ui/deriving/deriving-clone-struct.rs | 26 + .../ui/deriving/deriving-clone-tuple-struct.rs | 7 + src/test/ui/deriving/deriving-cmp-generic-enum.rs | 44 + .../deriving/deriving-cmp-generic-struct-enum.rs | 48 + .../ui/deriving/deriving-cmp-generic-struct.rs | 40 + .../deriving/deriving-cmp-generic-tuple-struct.rs | 38 + src/test/ui/deriving/deriving-cmp-shortcircuit.rs | 37 + src/test/ui/deriving/deriving-copyclone.rs | 38 + src/test/ui/deriving/deriving-default-box.rs | 15 + .../ui/deriving/deriving-enum-single-variant.rs | 12 + .../ui/deriving/deriving-eq-ord-boxed-slice.rs | 15 + src/test/ui/deriving/deriving-hash.rs | 76 + src/test/ui/deriving/deriving-in-fn.rs | 10 + src/test/ui/deriving/deriving-in-macro.rs | 16 + src/test/ui/deriving/deriving-meta-multiple.rs | 26 + src/test/ui/deriving/deriving-meta.rs | 23 + .../deriving-self-lifetime-totalord-totaleq.rs | 16 + src/test/ui/deriving/deriving-show-2.rs | 54 + src/test/ui/deriving/deriving-show.rs | 35 + .../ui/deriving/deriving-via-extension-c-enum.rs | 17 + .../ui/deriving/deriving-via-extension-enum.rs | 16 + .../deriving/deriving-via-extension-hash-enum.rs | 17 + .../deriving/deriving-via-extension-hash-struct.rs | 12 + .../deriving-via-extension-struct-empty.rs | 8 + ...iving-via-extension-struct-like-enum-variant.rs | 13 + .../deriving-via-extension-struct-tuple.rs | 17 + .../ui/deriving/deriving-via-extension-struct.rs | 16 + .../deriving/deriving-via-extension-type-params.rs | 16 + src/test/ui/deriving/deriving-with-repr-packed.rs | 36 + src/test/ui/dispatch_from_dyn_zst.rs | 51 + src/test/ui/diverging-fallback-control-flow.rs | 101 + src/test/ui/diverging-fallback-method-chain.rs | 20 + src/test/ui/diverging-fallback-option.rs | 14 + src/test/ui/double-ref.rs | 36 + .../drop/auxiliary/dropck_eyepatch_extern_crate.rs | 50 + src/test/ui/drop/drop-on-empty-block-exit.rs | 12 + src/test/ui/drop/drop-on-ret.rs | 15 + src/test/ui/drop/drop-struct-as-object.rs | 38 + src/test/ui/drop/drop-trait-enum.rs | 95 + src/test/ui/drop/drop-trait-generic.rs | 15 + src/test/ui/drop/drop-trait.rs | 15 + src/test/ui/drop/drop-uninhabited-enum.rs | 14 + src/test/ui/drop/drop-with-type-ascription-1.rs | 8 + src/test/ui/drop/drop-with-type-ascription-2.rs | 8 + src/test/ui/drop/dropck-eyepatch-extern-crate.rs | 39 + src/test/ui/drop/dropck-eyepatch-reorder.rs | 79 + src/test/ui/drop/dropck-eyepatch.rs | 102 + src/test/ui/drop/dropck_legal_cycles.rs | 1183 +++++++ src/test/ui/drop/dynamic-drop-async.rs | 328 ++ src/test/ui/drop/dynamic-drop.rs | 436 +++ src/test/ui/drop/no-drop-flag-size.rs | 15 + src/test/ui/drop/nondrop-cycle.rs | 31 + src/test/ui/dupe-first-attr.rc | 24 + src/test/ui/duplicated-external-mods.rs | 9 + .../dynamically-sized-types/dst-coerce-custom.rs | 43 + .../ui/dynamically-sized-types/dst-coerce-rc.rs | 42 + .../ui/dynamically-sized-types/dst-coercions.rs | 28 + .../ui/dynamically-sized-types/dst-deref-mut.rs | 35 + src/test/ui/dynamically-sized-types/dst-deref.rs | 30 + .../ui/dynamically-sized-types/dst-field-align.rs | 67 + src/test/ui/dynamically-sized-types/dst-index.rs | 34 + .../dst-irrefutable-bind.rs | 27 + src/test/ui/dynamically-sized-types/dst-raw.rs | 138 + .../ui/dynamically-sized-types/dst-struct-sole.rs | 76 + src/test/ui/dynamically-sized-types/dst-struct.rs | 122 + .../ui/dynamically-sized-types/dst-trait-tuple.rs | 103 + src/test/ui/dynamically-sized-types/dst-trait.rs | 105 + .../ui/dynamically-sized-types/dst-tuple-sole.rs | 79 + src/test/ui/dynamically-sized-types/dst-tuple.rs | 120 + src/test/ui/early-ret-binop-add.rs | 11 + src/test/ui/early-vtbl-resolution.rs | 19 + src/test/ui/edition-keywords-2015-2015.rs | 36 + src/test/ui/edition-keywords-2015-2018.rs | 36 + src/test/ui/edition-keywords-2018-2015.rs | 34 + src/test/ui/edition-keywords-2018-2018.rs | 34 + src/test/ui/else-if.rs | 20 + src/test/ui/empty-allocation-non-null.rs | 14 + src/test/ui/empty-allocation-rvalue-non-null.rs | 8 + src/test/ui/empty-type-parameter-list.rs | 24 + src/test/ui/empty_global_asm.rs | 20 + src/test/ui/env-args-reverse-iterator.rs | 39 + src/test/ui/env-funky-keys.rs | 42 + src/test/ui/env-home-dir.rs | 51 + src/test/ui/env-null-vars.rs | 23 + src/test/ui/env-vars.rs | 13 + src/test/ui/epoch-gate-feature.rs | 15 + src/test/ui/eq-multidispatch.rs | 30 + src/test/ui/estr-uniq.rs | 15 + src/test/ui/exec-env.rs | 11 + src/test/ui/existential_type.rs | 89 + src/test/ui/explicit-i-suffix.rs | 14 + src/test/ui/export-glob-imports-target.rs | 22 + src/test/ui/export-multi.rs | 12 + src/test/ui/export-non-interference2.rs | 11 + src/test/ui/export-non-interference3.rs | 11 + src/test/ui/expr-block-fn.rs | 9 + src/test/ui/expr-block-generic-unique1.rs | 19 + src/test/ui/expr-block-generic-unique2.rs | 15 + src/test/ui/expr-block-generic.rs | 26 + src/test/ui/expr-block-slot.rs | 13 + src/test/ui/expr-block-unique.rs | 5 + src/test/ui/expr-block.rs | 21 + src/test/ui/expr-copy.rs | 18 + src/test/ui/expr-empty-ret.rs | 15 + src/test/ui/expr-fn.rs | 61 + src/test/ui/expr-if-generic.rs | 29 + src/test/ui/expr-if-panic-all.rs | 11 + src/test/ui/expr-if-panic.rs | 18 + src/test/ui/expr-if-unique.rs | 11 + src/test/ui/expr-if.rs | 52 + src/test/ui/expr-scope.rs | 7 + src/test/ui/ext-expand-inner-exprs.rs | 7 + src/test/ui/extend-for-unit.rs | 12 + src/test/ui/exterior.rs | 24 + .../extern/auxiliary/extern-crosscrate-source.rs | 31 + src/test/ui/extern/auxiliary/extern-take-value.rs | 5 + .../extern/auxiliary/extern_calling_convention.rs | 26 + .../ui/extern/auxiliary/extern_mod_ordering_lib.rs | 5 + src/test/ui/extern/auxiliary/fat_drop.rs | 13 + src/test/ui/extern/extern-1.rs | 9 + src/test/ui/extern/extern-call-deep.rs | 39 + src/test/ui/extern/extern-call-deep2.rs | 44 + src/test/ui/extern/extern-call-direct.rs | 10 + src/test/ui/extern/extern-call-indirect.rs | 38 + src/test/ui/extern/extern-call-scrub.rs | 48 + .../ui/extern/extern-calling-convention-test.rs | 12 + .../ui/extern/extern-compare-with-return-type.rs | 25 + src/test/ui/extern/extern-crosscrate.rs | 21 + src/test/ui/extern/extern-foreign-crate.rs | 6 + src/test/ui/extern/extern-methods.rs | 30 + src/test/ui/extern/extern-mod-abi.rs | 9 + src/test/ui/extern/extern-mod-ordering-exe.rs | 12 + src/test/ui/extern/extern-pass-TwoU16s.rs | 25 + src/test/ui/extern/extern-pass-TwoU32s.rs | 25 + src/test/ui/extern/extern-pass-TwoU64s.rs | 25 + src/test/ui/extern/extern-pass-TwoU8s.rs | 25 + src/test/ui/extern/extern-pass-char.rs | 16 + src/test/ui/extern/extern-pass-double.rs | 13 + src/test/ui/extern/extern-pass-empty.rs | 55 + src/test/ui/extern/extern-pass-u32.rs | 16 + src/test/ui/extern/extern-pass-u64.rs | 16 + src/test/ui/extern/extern-prelude-core.rs | 18 + src/test/ui/extern/extern-prelude-core.stderr | 8 + .../ui/extern/extern-prelude-no-speculative.rs | 13 + src/test/ui/extern/extern-prelude-std.rs | 13 + src/test/ui/extern/extern-prelude-std.stderr | 8 + src/test/ui/extern/extern-pub.rs | 9 + src/test/ui/extern/extern-return-TwoU16s.rs | 21 + src/test/ui/extern/extern-return-TwoU32s.rs | 21 + src/test/ui/extern/extern-return-TwoU64s.rs | 21 + src/test/ui/extern/extern-return-TwoU8s.rs | 21 + src/test/ui/extern/extern-rust.rs | 12 + src/test/ui/extern/extern-take-value.rs | 13 + src/test/ui/extern/extern-thiscall.rs | 26 + src/test/ui/extern/extern-types-inherent-impl.rs | 19 + .../ui/extern/extern-types-manual-sync-send.rs | 19 + src/test/ui/extern/extern-types-pointer-cast.rs | 32 + src/test/ui/extern/extern-types-size_of_val.rs | 17 + src/test/ui/extern/extern-types-thin-pointer.rs | 43 + src/test/ui/extern/extern-types-trait-impl.rs | 27 + src/test/ui/extern/extern-vectorcall.rs | 26 + src/test/ui/extern/extern_fat_drop.rs | 13 + src/test/ui/extoption_env-not-defined.rs | 5 + src/test/ui/fact.rs | 26 + src/test/ui/fat-lto.rs | 7 + src/test/ui/fds-are-cloexec.rs | 83 + src/test/ui/filter-block-view-items.rs | 8 + src/test/ui/fixup-deref-mut.rs | 50 + src/test/ui/for-loop-while/auto-loop.rs | 10 + src/test/ui/for-loop-while/break-value.rs | 7 + src/test/ui/for-loop-while/break.rs | 25 + src/test/ui/for-loop-while/for-destruct.rs | 9 + src/test/ui/for-loop-while/for-loop-goofiness.rs | 16 + .../ui/for-loop-while/for-loop-has-unit-body.rs | 13 + .../ui/for-loop-while/for-loop-into-iterator.rs | 19 + .../for-loop-lifetime-of-unbound-values.rs | 34 + src/test/ui/for-loop-while/for-loop-macro.rs | 11 + .../ui/for-loop-while/for-loop-mut-ref-element.rs | 6 + src/test/ui/for-loop-while/for-loop-no-std.rs | 14 + src/test/ui/for-loop-while/for-loop-panic.rs | 4 + ...loop-unconstrained-element-type-i32-fallback.rs | 11 + .../foreach-external-iterators-break.rs | 13 + ...ach-external-iterators-hashmap-break-restart.rs | 33 + .../foreach-external-iterators-hashmap.rs | 19 + .../foreach-external-iterators-loop.rs | 13 + .../foreach-external-iterators-nested.rs | 15 + .../for-loop-while/foreach-external-iterators.rs | 10 + src/test/ui/for-loop-while/foreach-nested.rs | 16 + .../ui/for-loop-while/foreach-put-structured.rs | 22 + .../ui/for-loop-while/foreach-simple-outer-slot.rs | 16 + src/test/ui/for-loop-while/label_break_value.rs | 116 + src/test/ui/for-loop-while/labeled-break.rs | 22 + src/test/ui/for-loop-while/linear-for-loop.rs | 23 + .../liveness-assign-imm-local-after-loop.rs | 18 + src/test/ui/for-loop-while/liveness-loop-break.rs | 13 + .../ui/for-loop-while/liveness-move-in-loop.rs | 20 + src/test/ui/for-loop-while/loop-break-cont-1.rs | 9 + src/test/ui/for-loop-while/loop-break-cont.rs | 39 + src/test/ui/for-loop-while/loop-break-value.rs | 138 + src/test/ui/for-loop-while/loop-diverges.rs | 14 + src/test/ui/for-loop-while/loop-label-shadowing.rs | 11 + .../ui/for-loop-while/loop-labeled-break-value.rs | 11 + .../loop-no-reinit-needed-post-bot.rs | 34 + src/test/ui/for-loop-while/loop-scope.rs | 8 + src/test/ui/for-loop-while/while-cont.rs | 11 + src/test/ui/for-loop-while/while-flow-graph.rs | 6 + src/test/ui/for-loop-while/while-label.rs | 15 + src/test/ui/for-loop-while/while-let.rs | 46 + .../ui/for-loop-while/while-loop-constraints-2.rs | 15 + src/test/ui/for-loop-while/while-prelude-drop.rs | 24 + src/test/ui/for-loop-while/while-with-break.rs | 17 + src/test/ui/for-loop-while/while.rs | 13 + src/test/ui/foreign/auxiliary/fn-abi.rs | 2 + src/test/ui/foreign/auxiliary/foreign_lib.rs | 38 + src/test/ui/foreign/foreign-call-no-runtime.rs | 55 + src/test/ui/foreign/foreign-dupe.rs | 17 + src/test/ui/foreign/foreign-fn-linkname.rs | 30 + src/test/ui/foreign/foreign-fn-with-byval.rs | 32 + src/test/ui/foreign/foreign-int-types.rs | 13 + .../foreign/foreign-mod-src/compiletest-ignore-dir | 0 src/test/ui/foreign/foreign-mod-src/inner.rs | 14 + src/test/ui/foreign/foreign-mod-unused-const.rs | 12 + src/test/ui/foreign/foreign-no-abi.rs | 22 + .../ui/foreign/foreign-src/compiletest-ignore-dir | 0 src/test/ui/foreign/foreign-src/foreign.rs | 9 + src/test/ui/foreign/foreign-truncated-arguments.rs | 20 + src/test/ui/foreign/foreign2.rs | 30 + src/test/ui/format-hygiene.rs | 8 + src/test/ui/format-nan.rs | 9 + src/test/ui/format-no-std.rs | 28 + src/test/ui/format-ref-cell.rs | 10 + src/test/ui/fsu-moves-and-copies.rs | 95 + src/test/ui/fun-call-variants.rs | 12 + src/test/ui/fun-indirect-call.rs | 9 + src/test/ui/functions-closures/auxiliary/fn-abi.rs | 2 + .../call-closure-from-overloaded-op.rs | 9 + .../capture-clauses-boxed-closures.rs | 14 + .../capture-clauses-unboxed-closures.rs | 13 + src/test/ui/functions-closures/clone-closure.rs | 18 + .../closure-bounds-can-capture-chan.rs | 16 + .../closure-expected-type/README.md | 8 + .../expect-infer-supply-two-infers.rs | 19 + .../closure-expected-type/issue-38714.rs | 19 + .../supply-just-return-type.rs | 26 + .../closure-expected-type/supply-nothing.rs | 11 + .../ui/functions-closures/closure-immediate.rs | 13 + .../ui/functions-closures/closure-inference.rs | 11 + .../ui/functions-closures/closure-inference2.rs | 9 + src/test/ui/functions-closures/closure-reform.rs | 56 + .../closure-returning-closure.rs | 5 + .../functions-closures/closure-to-fn-coercion.rs | 35 + .../closure_to_fn_coercion-expected-types.rs | 9 + src/test/ui/functions-closures/copy-closure.rs | 16 + src/test/ui/functions-closures/fn-abi.rs | 18 + src/test/ui/functions-closures/fn-bare-assign.rs | 17 + .../functions-closures/fn-bare-coerce-to-block.rs | 10 + src/test/ui/functions-closures/fn-bare-item.rs | 8 + src/test/ui/functions-closures/fn-bare-size.rs | 8 + src/test/ui/functions-closures/fn-bare-spawn.rs | 15 + src/test/ui/functions-closures/fn-coerce-field.rs | 13 + .../ui/functions-closures/fn-item-type-cast.rs | 22 + .../ui/functions-closures/fn-item-type-coerce.rs | 17 + .../functions-closures/fn-item-type-zero-sized.rs | 13 + src/test/ui/functions-closures/fn-lval.rs | 11 + src/test/ui/functions-closures/fn-type-infer.rs | 11 + .../implied-bounds-closure-arg-outlives.rs | 35 + .../nullable-pointer-opt-closures.rs | 34 + .../parallel-codegen-closures.rs | 28 + .../ui/functions-closures/return-from-closure.rs | 33 + src/test/ui/generator/addassign-yield.rs | 35 + .../ui/generator/auxiliary/xcrate-reachable.rs | 14 + src/test/ui/generator/auxiliary/xcrate.rs | 18 + src/test/ui/generator/borrow-in-tail-expr.rs | 11 + src/test/ui/generator/conditional-drop.rs | 58 + src/test/ui/generator/control-flow.rs | 50 + src/test/ui/generator/drop-and-replace.rs | 45 + src/test/ui/generator/drop-env.rs | 63 + src/test/ui/generator/issue-44197.rs | 33 + src/test/ui/generator/issue-52398.rs | 28 + src/test/ui/generator/issue-57084.rs | 28 + src/test/ui/generator/issue-58888.rs | 27 + src/test/ui/generator/iterator-count.rs | 44 + src/test/ui/generator/live-upvar-across-yield.rs | 14 + src/test/ui/generator/match-bindings.rs | 23 + src/test/ui/generator/nested_generators.rs | 21 + src/test/ui/generator/non-static-is-unpin.rs | 18 + src/test/ui/generator/overlap-locals.rs | 29 + src/test/ui/generator/panic-drops.rs | 57 + src/test/ui/generator/panic-safe.rs | 30 + src/test/ui/generator/pin-box-generator.rs | 13 + src/test/ui/generator/reborrow-mut-upvar.rs | 16 + src/test/ui/generator/resume-after-return.rs | 28 + src/test/ui/generator/size-moved-locals.rs | 76 + src/test/ui/generator/smoke.rs | 174 + src/test/ui/generator/static-generators.rs | 20 + .../generator/too-live-local-in-immovable-gen.rs | 21 + src/test/ui/generator/xcrate-reachable.rs | 14 + src/test/ui/generator/xcrate.rs | 30 + src/test/ui/generator/yield-in-args-rev.rs | 19 + src/test/ui/generator/yield-in-box.rs | 18 + src/test/ui/generator/yield-in-initializer.rs | 17 + src/test/ui/generator/yield-subtype.rs | 17 + .../generics/auxiliary/default_type_params_xc.rs | 5 + src/test/ui/generics/generic-alias-unique.rs | 11 + .../generic-default-type-params-cross-crate.rs | 17 + .../ui/generics/generic-default-type-params.rs | 53 + src/test/ui/generics/generic-derived-type.rs | 21 + src/test/ui/generics/generic-exterior-unique.rs | 12 + src/test/ui/generics/generic-extern-mangle.rs | 9 + src/test/ui/generics/generic-fn-infer.rs | 10 + src/test/ui/generics/generic-fn-twice.rs | 11 + src/test/ui/generics/generic-fn-unique.rs | 6 + src/test/ui/generics/generic-fn.rs | 28 + src/test/ui/generics/generic-ivec-leak.rs | 5 + src/test/ui/generics/generic-newtype-struct.rs | 8 + src/test/ui/generics/generic-object.rs | 22 + src/test/ui/generics/generic-recursive-tag.rs | 13 + src/test/ui/generics/generic-static-methods.rs | 21 + src/test/ui/generics/generic-tag-corruption.rs | 10 + src/test/ui/generics/generic-tag-local.rs | 8 + src/test/ui/generics/generic-tag-match.rs | 13 + src/test/ui/generics/generic-tag-values.rs | 20 + src/test/ui/generics/generic-tag.rs | 15 + src/test/ui/generics/generic-temporary.rs | 16 + src/test/ui/generics/generic-tup.rs | 8 + src/test/ui/generics/generic-type-synonym.rs | 15 + src/test/ui/generics/generic-type.rs | 11 + src/test/ui/generics/generic-unique.rs | 12 + src/test/ui/global-scope.rs | 13 + src/test/ui/guards-not-exhaustive.rs | 18 + src/test/ui/guards.rs | 20 + src/test/ui/hashmap-memory.rs | 94 + src/test/ui/hello.rs | 5 + .../hrtb-binder-levels-in-object-types.rs | 29 + .../hrtb-debruijn-object-types-in-closures.rs | 16 + .../hrtb-fn-like-trait-object.rs | 27 + .../higher-rank-trait-bounds/hrtb-fn-like-trait.rs | 27 + .../higher-rank-trait-bounds/hrtb-opt-in-copy.rs | 28 + src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs | 36 + .../hrtb-precedence-of-plus-where-clause.rs | 25 + .../hrtb-precedence-of-plus.rs | 13 + .../hrtb-resolve-lifetime.rs | 14 + .../hrtb-trait-object-paren-notation.rs | 26 + .../hrtb-trait-object-passed-to-closure.rs | 25 + .../higher-rank-trait-bounds/hrtb-type-outlives.rs | 48 + .../hrtb-unboxed-closure-trait.rs | 11 + src/test/ui/html-literals.rs | 94 + src/test/ui/if-bot.rs | 6 + src/test/ui/if-check.rs | 17 + src/test/ui/if-ret.rs | 8 + src/test/ui/ifmt.rs | 323 ++ src/test/ui/ignore-all-the-things.rs | 47 + src/test/ui/impl-for-never.rs | 26 + src/test/ui/impl-inherent-non-conflict.rs | 23 + src/test/ui/impl-not-adjacent-to-type.rs | 16 + src/test/ui/impl-privacy-xc-1.rs | 11 + src/test/ui/impl-privacy-xc-2.rs | 10 + src/test/ui/impl-trait-in-bindings.rs | 49 + src/test/ui/impl-trait-in-bindings.stderr | 6 + src/test/ui/impl-trait/auxiliary/xcrate.rs | 23 + src/test/ui/impl-trait/bounds_regression.rs | 24 + src/test/ui/impl-trait/example-calendar.rs | 857 +++++ src/test/ui/impl-trait/example-st.rs | 30 + src/test/ui/impl-trait/lifetimes.rs | 123 + src/test/ui/impl-trait/nesting.rs | 15 + src/test/ui/impl-trait/universal_hrtb_anon.rs | 10 + src/test/ui/impl-trait/universal_hrtb_named.rs | 10 + .../impl-trait/universal_in_adt_in_parameters.rs | 22 + .../universal_in_impl_trait_in_parameters.rs | 30 + .../universal_in_trait_defn_parameters.rs | 18 + .../ui/impl-trait/universal_multiple_bounds.rs | 13 + src/test/ui/impl-trait/xcrate.rs | 11 + src/test/ui/impl-trait/xcrate_simple.rs | 9 + .../auxiliary/crate_with_invalid_spans.rs | 20 + .../auxiliary/crate_with_invalid_spans_macros.rs | 7 + .../import-crate-with-invalid-spans/main.rs | 13 + src/test/ui/imports/import-from.rs | 11 + src/test/ui/imports/import-glob-1.rs | 27 + src/test/ui/imports/import-glob-crate.rs | 19 + src/test/ui/imports/import-in-block.rs | 13 + src/test/ui/imports/import-prefix-macro.rs | 27 + src/test/ui/imports/import-rename.rs | 13 + src/test/ui/imports/import-trailing-comma.rs | 13 + src/test/ui/imports/import.rs | 12 + src/test/ui/imports/import2.rs | 9 + src/test/ui/imports/import3.rs | 13 + src/test/ui/imports/import4.rs | 9 + src/test/ui/imports/import5.rs | 10 + src/test/ui/imports/import6.rs | 15 + src/test/ui/imports/import7.rs | 18 + src/test/ui/imports/import8.rs | 10 + src/test/ui/imports/imports.rs | 66 + src/test/ui/in-band-lifetimes.rs | 96 + src/test/ui/inc-range-pat.rs | 12 + src/test/ui/infer-fn-tail-expr.rs | 11 + src/test/ui/inherit-env.rs | 26 + src/test/ui/init-large-type.rs | 26 + src/test/ui/init-res-into-things.rs | 82 + src/test/ui/inlined-main.rs | 4 + src/test/ui/inner-attrs-on-impl.rs | 24 + src/test/ui/inner-module.rs | 10 + src/test/ui/inner-static.rs | 14 + src/test/ui/instantiable.rs | 17 + src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs | 14 + src/test/ui/intrinsics/intrinsic-alignment.rs | 74 + src/test/ui/intrinsics/intrinsic-assume.rs | 17 + src/test/ui/intrinsics/intrinsic-atomics-cc.rs | 12 + src/test/ui/intrinsics/intrinsic-atomics.rs | 103 + .../ui/intrinsics/intrinsic-move-val-cleanups.rs | 190 ++ src/test/ui/intrinsics/intrinsic-move-val.rs | 82 + src/test/ui/intrinsics/intrinsic-unreachable.rs | 17 + src/test/ui/intrinsics/intrinsics-integer.rs | 172 + src/test/ui/intrinsics/intrinsics-math.rs | 60 + src/test/ui/invalid_const_promotion.rs | 56 + src/test/ui/invoke-external-foreign.rs | 17 + src/test/ui/irrefutable-unit.rs | 6 + src/test/ui/issue-59020.rs | 28 + src/test/ui/issues/.gitattributes | 1 + src/test/ui/issues/auxiliary/cgu_test.rs | 6 + src/test/ui/issues/auxiliary/cgu_test_a.rs | 15 + src/test/ui/issues/auxiliary/cgu_test_b.rs | 15 + src/test/ui/issues/auxiliary/i8.rs | 3 + src/test/ui/issues/auxiliary/iss.rs | 12 + src/test/ui/issues/auxiliary/issue-10028.rs | 9 + src/test/ui/issues/auxiliary/issue-10031-aux.rs | 1 + src/test/ui/issues/auxiliary/issue-11224.rs | 16 + src/test/ui/issues/auxiliary/issue-11225-1.rs | 18 + src/test/ui/issues/auxiliary/issue-11225-2.rs | 28 + src/test/ui/issues/auxiliary/issue-11225-3.rs | 28 + src/test/ui/issues/auxiliary/issue-11508.rs | 10 + src/test/ui/issues/auxiliary/issue-11529.rs | 1 + src/test/ui/issues/auxiliary/issue-12133-dylib.rs | 1 + src/test/ui/issues/auxiliary/issue-12133-dylib2.rs | 6 + src/test/ui/issues/auxiliary/issue-12133-rlib.rs | 3 + src/test/ui/issues/auxiliary/issue-12612-1.rs | 3 + src/test/ui/issues/auxiliary/issue-12612-2.rs | 1 + src/test/ui/issues/auxiliary/issue-12660-aux.rs | 11 + src/test/ui/issues/auxiliary/issue-13507.rs | 87 + src/test/ui/issues/auxiliary/issue-13620-1.rs | 9 + src/test/ui/issues/auxiliary/issue-13620-2.rs | 3 + src/test/ui/issues/auxiliary/issue-13872-1.rs | 1 + src/test/ui/issues/auxiliary/issue-13872-2.rs | 3 + src/test/ui/issues/auxiliary/issue-13872-3.rs | 9 + src/test/ui/issues/auxiliary/issue-14344-1.rs | 5 + src/test/ui/issues/auxiliary/issue-14344-2.rs | 3 + src/test/ui/issues/auxiliary/issue-14421.rs | 25 + src/test/ui/issues/auxiliary/issue-14422.rs | 25 + src/test/ui/issues/auxiliary/issue-15562.rs | 5 + src/test/ui/issues/auxiliary/issue-16643.rs | 19 + src/test/ui/issues/auxiliary/issue-17662.rs | 12 + src/test/ui/issues/auxiliary/issue-17718-aux.rs | 10 + src/test/ui/issues/auxiliary/issue-18501.rs | 17 + src/test/ui/issues/auxiliary/issue-18514.rs | 17 + src/test/ui/issues/auxiliary/issue-18711.rs | 5 + src/test/ui/issues/auxiliary/issue-18913-1.rs | 6 + src/test/ui/issues/auxiliary/issue-18913-2.rs | 6 + src/test/ui/issues/auxiliary/issue-19293.rs | 4 + src/test/ui/issues/auxiliary/issue-19340-1.rs | 3 + src/test/ui/issues/auxiliary/issue-20389.rs | 4 + src/test/ui/issues/auxiliary/issue-2170-lib.rs | 18 + src/test/ui/issues/auxiliary/issue-2316-a.rs | 3 + src/test/ui/issues/auxiliary/issue-2316-b.rs | 11 + src/test/ui/issues/auxiliary/issue-2380.rs | 15 + src/test/ui/issues/auxiliary/issue-2414-a.rs | 12 + src/test/ui/issues/auxiliary/issue-2414-b.rs | 4 + src/test/ui/issues/auxiliary/issue-2472-b.rs | 13 + src/test/ui/issues/auxiliary/issue-25185-1.rs | 8 + src/test/ui/issues/auxiliary/issue-25185-2.rs | 3 + src/test/ui/issues/auxiliary/issue-2526.rs | 44 + src/test/ui/issues/auxiliary/issue-25467.rs | 10 + src/test/ui/issues/auxiliary/issue-2631-a.rs | 14 + src/test/ui/issues/auxiliary/issue-2723-a.rs | 3 + src/test/ui/issues/auxiliary/issue-29485.rs | 16 + src/test/ui/issues/auxiliary/issue-3012-1.rs | 20 + src/test/ui/issues/auxiliary/issue-3136-a.rc | 4 + src/test/ui/issues/auxiliary/issue-3136-a.rs | 14 + src/test/ui/issues/auxiliary/issue-31702-1.rs | 16 + src/test/ui/issues/auxiliary/issue-31702-2.rs | 20 + src/test/ui/issues/auxiliary/issue-34796-aux.rs | 20 + src/test/ui/issues/auxiliary/issue-36954.rs | 7 + src/test/ui/issues/auxiliary/issue-38190.rs | 2 + src/test/ui/issues/auxiliary/issue-38226-aux.rs | 23 + src/test/ui/issues/auxiliary/issue-38715-modern.rs | 7 + src/test/ui/issues/auxiliary/issue-38715.rs | 7 + src/test/ui/issues/auxiliary/issue-3979-traits.rs | 15 + src/test/ui/issues/auxiliary/issue-39823.rs | 7 + src/test/ui/issues/auxiliary/issue-40469.rs | 1 + src/test/ui/issues/auxiliary/issue-41053.rs | 1 + src/test/ui/issues/auxiliary/issue-41394.rs | 16 + src/test/ui/issues/auxiliary/issue-42007-s.rs | 4 + src/test/ui/issues/auxiliary/issue-4208-cc.rs | 10 + src/test/ui/issues/auxiliary/issue-4545.rs | 2 + src/test/ui/issues/auxiliary/issue-48984-aux.rs | 6 + src/test/ui/issues/auxiliary/issue-5518.rs | 4 + src/test/ui/issues/auxiliary/issue-5521.rs | 3 + src/test/ui/issues/auxiliary/issue-7178.rs | 7 + src/test/ui/issues/auxiliary/issue-7899.rs | 1 + src/test/ui/issues/auxiliary/issue-8044.rs | 15 + src/test/ui/issues/auxiliary/issue-8259.rs | 4 + src/test/ui/issues/auxiliary/issue-8401.rs | 16 + src/test/ui/issues/auxiliary/issue-9123.rs | 9 + src/test/ui/issues/auxiliary/issue-9155.rs | 7 + src/test/ui/issues/auxiliary/issue-9188.rs | 13 + src/test/ui/issues/auxiliary/issue-9906.rs | 15 + src/test/ui/issues/auxiliary/issue-9968.rs | 22 + src/test/ui/issues/issue-10025.rs | 11 + src/test/ui/issues/issue-10028.rs | 21 + src/test/ui/issues/issue-10031.rs | 9 + src/test/ui/issues/issue-10228.rs | 20 + src/test/ui/issues/issue-10392.rs | 30 + src/test/ui/issues/issue-10436.rs | 11 + src/test/ui/issues/issue-10626.rs | 27 + src/test/ui/issues/issue-10638.rs | 11 + src/test/ui/issues/issue-10682.rs | 15 + src/test/ui/issues/issue-10683.rs | 11 + src/test/ui/issues/issue-10718.rs | 11 + src/test/ui/issues/issue-10734.rs | 36 + src/test/ui/issues/issue-10767.rs | 10 + src/test/ui/issues/issue-10802.rs | 46 + src/test/ui/issues/issue-10806.rs | 38 + src/test/ui/issues/issue-11047.rs | 26 + src/test/ui/issues/issue-11085.rs | 46 + src/test/ui/issues/issue-1112.rs | 37 + src/test/ui/issues/issue-11205.rs | 85 + src/test/ui/issues/issue-11224.rs | 8 + src/test/ui/issues/issue-11225-1.rs | 11 + src/test/ui/issues/issue-11225-2.rs | 11 + src/test/ui/issues/issue-11225-3.rs | 11 + src/test/ui/issues/issue-11267.rs | 19 + src/test/ui/issues/issue-11382.rs | 4 + src/test/ui/issues/issue-11508.rs | 11 + src/test/ui/issues/issue-11529.rs | 11 + src/test/ui/issues/issue-11552.rs | 22 + src/test/ui/issues/issue-11577.rs | 18 + src/test/ui/issues/issue-11677.rs | 23 + src/test/ui/issues/issue-11709.rs | 38 + src/test/ui/issues/issue-11820.rs | 12 + src/test/ui/issues/issue-11940.rs | 11 + src/test/ui/issues/issue-11958.rs | 10 + src/test/ui/issues/issue-12033.rs | 7 + src/test/ui/issues/issue-12133-1.rs | 10 + src/test/ui/issues/issue-12133-2.rs | 11 + src/test/ui/issues/issue-12133-3.rs | 14 + src/test/ui/issues/issue-12285.rs | 14 + src/test/ui/issues/issue-1257.rs | 11 + src/test/ui/issues/issue-12582.rs | 21 + src/test/ui/issues/issue-12612.rs | 15 + src/test/ui/issues/issue-12660.rs | 14 + src/test/ui/issues/issue-12677.rs | 9 + src/test/ui/issues/issue-12699.rs | 10 + src/test/ui/issues/issue-12744.rs | 5 + src/test/ui/issues/issue-12860.rs | 49 + src/test/ui/issues/issue-12909.rs | 20 + src/test/ui/issues/issue-13027.rs | 178 + src/test/ui/issues/issue-13204.rs | 25 + .../ui/issues/issue-13259-windows-tcb-trash.rs | 42 + src/test/ui/issues/issue-13264.rs | 74 + src/test/ui/issues/issue-13304.rs | 40 + src/test/ui/issues/issue-13323.rs | 59 + src/test/ui/issues/issue-13434.rs | 21 + src/test/ui/issues/issue-13507-2.rs | 36 + src/test/ui/issues/issue-13620.rs | 11 + src/test/ui/issues/issue-13655.rs | 32 + src/test/ui/issues/issue-13665.rs | 15 + src/test/ui/issues/issue-13763.rs | 15 + src/test/ui/issues/issue-13808.rs | 18 + src/test/ui/issues/issue-13867.rs | 49 + src/test/ui/issues/issue-13872.rs | 12 + src/test/ui/issues/issue-13902.rs | 16 + src/test/ui/issues/issue-14229.rs | 21 + src/test/ui/issues/issue-14308.rs | 15 + src/test/ui/issues/issue-14344.rs | 11 + src/test/ui/issues/issue-14382.rs | 15 + src/test/ui/issues/issue-14393.rs | 10 + src/test/ui/issues/issue-14399.rs | 20 + src/test/ui/issues/issue-14421.rs | 16 + src/test/ui/issues/issue-14422.rs | 16 + src/test/ui/issues/issue-14456.rs | 38 + src/test/ui/issues/issue-1451.rs | 27 + src/test/ui/issues/issue-14589.rs | 24 + src/test/ui/issues/issue-1460.rs | 7 + src/test/ui/issues/issue-14821.rs | 21 + src/test/ui/issues/issue-14865.rs | 23 + src/test/ui/issues/issue-14875.rs | 35 + src/test/ui/issues/issue-14919.rs | 55 + src/test/ui/issues/issue-14940.rs | 20 + src/test/ui/issues/issue-14958.rs | 31 + src/test/ui/issues/issue-15043.rs | 14 + src/test/ui/issues/issue-15063.rs | 12 + src/test/ui/issues/issue-15080.rs | 23 + src/test/ui/issues/issue-15104.rs | 14 + src/test/ui/issues/issue-15155.rs | 21 + src/test/ui/issues/issue-15189.rs | 10 + src/test/ui/issues/issue-15221.rs | 16 + src/test/ui/issues/issue-15444.rs | 23 + src/test/ui/issues/issue-15487.rs | 13 + src/test/ui/issues/issue-15523-big.rs | 39 + src/test/ui/issues/issue-15523.rs | 42 + src/test/ui/issues/issue-15562.rs | 19 + src/test/ui/issues/issue-15571.rs | 58 + src/test/ui/issues/issue-15673.rs | 9 + src/test/ui/issues/issue-15689-1.rs | 10 + src/test/ui/issues/issue-15730.rs | 9 + src/test/ui/issues/issue-15734.rs | 58 + src/test/ui/issues/issue-15763.rs | 89 + src/test/ui/issues/issue-15774.rs | 25 + src/test/ui/issues/issue-15793.rs | 27 + src/test/ui/issues/issue-15858.rs | 33 + .../ui/issues/issue-15881-model-lexer-dotdotdot.rs | 38 + src/test/ui/issues/issue-16151.rs | 29 + src/test/ui/issues/issue-16256.rs | 7 + src/test/ui/issues/issue-16272.rs | 24 + src/test/ui/issues/issue-16278.rs | 10 + src/test/ui/issues/issue-16441.rs | 11 + src/test/ui/issues/issue-16452.rs | 10 + src/test/ui/issues/issue-16492.rs | 67 + src/test/ui/issues/issue-16530.rs | 15 + src/test/ui/issues/issue-16560.rs | 18 + src/test/ui/issues/issue-16597-empty.rs | 5 + src/test/ui/issues/issue-16597.rs | 10 + src/test/ui/issues/issue-1660.rs | 8 + src/test/ui/issues/issue-16602-1.rs | 6 + src/test/ui/issues/issue-16602-2.rs | 12 + src/test/ui/issues/issue-16602-3.rs | 27 + src/test/ui/issues/issue-16643.rs | 10 + src/test/ui/issues/issue-16648.rs | 11 + src/test/ui/issues/issue-16671.rs | 12 + src/test/ui/issues/issue-16739.rs | 50 + src/test/ui/issues/issue-16745.rs | 11 + src/test/ui/issues/issue-16774.rs | 46 + src/test/ui/issues/issue-16783.rs | 8 + src/test/ui/issues/issue-16819.rs | 12 + src/test/ui/issues/issue-1696.rs | 8 + src/test/ui/issues/issue-1701.rs | 26 + src/test/ui/issues/issue-17068.rs | 12 + src/test/ui/issues/issue-17074.rs | 15 + src/test/ui/issues/issue-17170.rs | 11 + src/test/ui/issues/issue-17216.rs | 21 + src/test/ui/issues/issue-17233.rs | 17 + src/test/ui/issues/issue-17302.rs | 26 + src/test/ui/issues/issue-17322.rs | 15 + src/test/ui/issues/issue-17351.rs | 10 + src/test/ui/issues/issue-17361.rs | 9 + src/test/ui/issues/issue-17503.rs | 10 + src/test/ui/issues/issue-17662.rs | 17 + src/test/ui/issues/issue-17718-borrow-interior.rs | 19 + src/test/ui/issues/issue-17718-parse-const.rs | 7 + .../issues/issue-17718-static-unsafe-interior.rs | 52 + src/test/ui/issues/issue-17718.rs | 75 + src/test/ui/issues/issue-17734.rs | 15 + src/test/ui/issues/issue-17756.rs | 8 + src/test/ui/issues/issue-17771.rs | 21 + src/test/ui/issues/issue-17816.rs | 10 + src/test/ui/issues/issue-17877.rs | 14 + src/test/ui/issues/issue-17897.rs | 8 + src/test/ui/issues/issue-18060.rs | 8 + src/test/ui/issues/issue-18075.rs | 7 + src/test/ui/issues/issue-18110.rs | 7 + src/test/ui/issues/issue-18173.rs | 12 + src/test/ui/issues/issue-18232.rs | 22 + src/test/ui/issues/issue-18352.rs | 14 + src/test/ui/issues/issue-18353.rs | 15 + src/test/ui/issues/issue-18412.rs | 26 + src/test/ui/issues/issue-18425.rs | 9 + src/test/ui/issues/issue-18464.rs | 12 + src/test/ui/issues/issue-18501.rs | 13 + src/test/ui/issues/issue-18514.rs | 16 + src/test/ui/issues/issue-18539.rs | 16 + src/test/ui/issues/issue-18652.rs | 10 + src/test/ui/issues/issue-18655.rs | 22 + src/test/ui/issues/issue-18661.rs | 19 + src/test/ui/issues/issue-18685.rs | 21 + src/test/ui/issues/issue-18711.rs | 12 + src/test/ui/issues/issue-18767.rs | 10 + src/test/ui/issues/issue-18804/auxiliary/lib.rs | 10 + src/test/ui/issues/issue-18804/main.rs | 19 + src/test/ui/issues/issue-18845.rs | 16 + src/test/ui/issues/issue-18859.rs | 16 + src/test/ui/issues/issue-18913.rs | 9 + src/test/ui/issues/issue-18937-1.rs | 21 + src/test/ui/issues/issue-18952.rs | 56 + src/test/ui/issues/issue-19001.rs | 11 + src/test/ui/issues/issue-19127.rs | 10 + src/test/ui/issues/issue-19135.rs | 13 + src/test/ui/issues/issue-19244.rs | 34 + src/test/ui/issues/issue-19293.rs | 10 + src/test/ui/issues/issue-19340-1.rs | 17 + src/test/ui/issues/issue-19340-2.rs | 24 + src/test/ui/issues/issue-19358.rs | 20 + src/test/ui/issues/issue-19367.rs | 32 + src/test/ui/issues/issue-19499.rs | 15 + src/test/ui/issues/issue-1974.rs | 11 + src/test/ui/issues/issue-19811-escape-unicode.rs | 9 + src/test/ui/issues/issue-20055-box-trait.rs | 41 + .../ui/issues/issue-20055-box-unsized-array.rs | 29 + src/test/ui/issues/issue-20174.rs | 7 + src/test/ui/issues/issue-20343.rs | 32 + src/test/ui/issues/issue-20389.rs | 15 + src/test/ui/issues/issue-20427.rs | 88 + src/test/ui/issues/issue-20544.rs | 18 + src/test/ui/issues/issue-20575.rs | 10 + src/test/ui/issues/issue-20616.rs | 44 + src/test/ui/issues/issue-2063.rs | 22 + src/test/ui/issues/issue-20676.rs | 12 + src/test/ui/issues/issue-2074.rs | 16 + src/test/ui/issues/issue-20803.rs | 10 + src/test/ui/issues/issue-20823.rs | 5 + src/test/ui/issues/issue-20847.rs | 12 + src/test/ui/issues/issue-20953.rs | 12 + src/test/ui/issues/issue-21033.rs | 49 + src/test/ui/issues/issue-21058.rs | 64 + src/test/ui/issues/issue-21291.rs | 10 + src/test/ui/issues/issue-21306.rs | 9 + src/test/ui/issues/issue-21361.rs | 11 + src/test/ui/issues/issue-21384.rs | 21 + src/test/ui/issues/issue-21400.rs | 56 + src/test/ui/issues/issue-21475.rs | 19 + src/test/ui/issues/issue-21486.rs | 77 + src/test/ui/issues/issue-21655.rs | 12 + src/test/ui/issues/issue-2170-exe.rs | 9 + src/test/ui/issues/issue-21721.rs | 9 + src/test/ui/issues/issue-2190-1.rs | 26 + src/test/ui/issues/issue-21909.rs | 15 + src/test/ui/issues/issue-21922.rs | 17 + src/test/ui/issues/issue-22008.rs | 9 + src/test/ui/issues/issue-22036.rs | 25 + src/test/ui/issues/issue-2214.rs | 41 + src/test/ui/issues/issue-2216.rs | 24 + src/test/ui/issues/issue-22258.rs | 10 + src/test/ui/issues/issue-22346.rs | 11 + src/test/ui/issues/issue-22403.rs | 6 + src/test/ui/issues/issue-22426.rs | 9 + src/test/ui/issues/issue-22463.rs | 20 + src/test/ui/issues/issue-22536-copy-mustnt-zero.rs | 28 + src/test/ui/issues/issue-22546.rs | 52 + src/test/ui/issues/issue-22577.rs | 27 + src/test/ui/issues/issue-22629.rs | 14 + src/test/ui/issues/issue-22828.rs | 23 + src/test/ui/issues/issue-2284.rs | 14 + src/test/ui/issues/issue-22864-1.rs | 7 + src/test/ui/issues/issue-22864-2.rs | 7 + src/test/ui/issues/issue-2288.rs | 35 + src/test/ui/issues/issue-22992-2.rs | 18 + src/test/ui/issues/issue-22992.rs | 76 + src/test/ui/issues/issue-23036.rs | 11 + src/test/ui/issues/issue-2316-c.rs | 12 + src/test/ui/issues/issue-23208.rs | 26 + src/test/ui/issues/issue-23261.rs | 61 + src/test/ui/issues/issue-23304-1.rs | 25 + src/test/ui/issues/issue-23304-2.rs | 13 + src/test/ui/issues/issue-23311.rs | 12 + src/test/ui/issues/issue-23336.rs | 11 + .../issues/issue-23338-ensure-param-drop-order.rs | 164 + .../issue-23338-params-outlive-temps-of-body.rs | 30 + src/test/ui/issues/issue-23433.rs | 13 + src/test/ui/issues/issue-23485.rs | 50 + src/test/ui/issues/issue-23491.rs | 9 + .../ui/issues/issue-23611-enum-swap-in-drop.rs | 258 ++ src/test/ui/issues/issue-23649-1.rs | 12 + src/test/ui/issues/issue-23649-2.rs | 11 + src/test/ui/issues/issue-23699.rs | 14 + src/test/ui/issues/issue-23781.rs | 29 + src/test/ui/issues/issue-2380-b.rs | 10 + src/test/ui/issues/issue-23808.rs | 59 + src/test/ui/issues/issue-23825.rs | 21 + src/test/ui/issues/issue-2383.rs | 9 + src/test/ui/issues/issue-23833.rs | 17 + src/test/ui/issues/issue-23891.rs | 11 + src/test/ui/issues/issue-23898.rs | 10 + src/test/ui/issues/issue-23958.rs | 13 + .../ui/issues/issue-23968-const-not-overflow.rs | 12 + src/test/ui/issues/issue-23992.rs | 19 + src/test/ui/issues/issue-24010.rs | 14 + src/test/ui/issues/issue-24086.rs | 23 + src/test/ui/issues/issue-2414-c.rs | 9 + src/test/ui/issues/issue-2428.rs | 14 + src/test/ui/issues/issue-24308.rs | 17 + src/test/ui/issues/issue-24313.rs | 33 + src/test/ui/issues/issue-24353.rs | 8 + src/test/ui/issues/issue-2445-b.rs | 31 + src/test/ui/issues/issue-2445.rs | 29 + src/test/ui/issues/issue-24533.rs | 24 + ...ue-24535-allow-mutable-borrow-in-match-guard.rs | 57 + src/test/ui/issues/issue-24589.rs | 17 + src/test/ui/issues/issue-2463.rs | 25 + .../auxiliary/issue-24687-lib.rs | 10 + .../auxiliary/issue-24687-mbcs-in-comments.rs | 27 + .../ui/issues/issue-24687-embed-debuginfo/main.rs | 13 + src/test/ui/issues/issue-2472.rs | 14 + src/test/ui/issues/issue-24779.rs | 4 + src/test/ui/issues/issue-24805-dropck-itemless.rs | 77 + src/test/ui/issues/issue-24945-repeat-dash-opts.rs | 9 + src/test/ui/issues/issue-24947.rs | 25 + src/test/ui/issues/issue-24954.rs | 13 + src/test/ui/issues/issue-25089.rs | 33 + src/test/ui/issues/issue-25145.rs | 13 + src/test/ui/issues/issue-25185.rs | 13 + src/test/ui/issues/issue-2526-a.rs | 11 + src/test/ui/issues/issue-25279.rs | 16 + src/test/ui/issues/issue-25339.rs | 31 + src/test/ui/issues/issue-25343.rs | 22 + src/test/ui/issues/issue-25467.rs | 12 + src/test/ui/issues/issue-25497.rs | 19 + src/test/ui/issues/issue-2550.rs | 22 + src/test/ui/issues/issue-25515.rs | 20 + src/test/ui/issues/issue-25549-multiple-drop.rs | 33 + src/test/ui/issues/issue-25679.rs | 19 + src/test/ui/issues/issue-25693.rs | 22 + src/test/ui/issues/issue-25700-1.rs | 13 + src/test/ui/issues/issue-25700-2.rs | 22 + src/test/ui/issues/issue-25746-bool-transmute.rs | 11 + src/test/ui/issues/issue-25757.rs | 18 + src/test/ui/issues/issue-25810.rs | 28 + src/test/ui/issues/issue-25916.rs | 28 + src/test/ui/issues/issue-26127.rs | 12 + src/test/ui/issues/issue-26251.rs | 13 + src/test/ui/issues/issue-2631-b.rs | 17 + src/test/ui/issues/issue-26322.rs | 30 + src/test/ui/issues/issue-2633-2.rs | 14 + src/test/ui/issues/issue-2633.rs | 31 + src/test/ui/issues/issue-2642.rs | 10 + src/test/ui/issues/issue-26468.rs | 29 + src/test/ui/issues/issue-26484.rs | 11 + src/test/ui/issues/issue-26641.rs | 6 + src/test/ui/issues/issue-26655.rs | 25 + src/test/ui/issues/issue-26709.rs | 17 + src/test/ui/issues/issue-26802.rs | 14 + src/test/ui/issues/issue-26805.rs | 6 + src/test/ui/issues/issue-26873-multifile.rs | 11 + src/test/ui/issues/issue-26873-multifile/A/B.rs | 4 + src/test/ui/issues/issue-26873-multifile/A/C.rs | 6 + src/test/ui/issues/issue-26873-multifile/A/mod.rs | 5 + .../issue-26873-multifile/compiletest-ignore-dir | 0 src/test/ui/issues/issue-26873-multifile/mod.rs | 4 + src/test/ui/issues/issue-26873-onefile.rs | 25 + src/test/ui/issues/issue-26996.rs | 24 + src/test/ui/issues/issue-27021.rs | 28 + .../ui/issues/issue-27054-primitive-binary-ops.rs | 5 + src/test/ui/issues/issue-2708.rs | 30 + src/test/ui/issues/issue-2718.rs | 327 ++ src/test/ui/issues/issue-2723-b.rs | 11 + src/test/ui/issues/issue-27240.rs | 26 + src/test/ui/issues/issue-27268.rs | 4 + src/test/ui/issues/issue-27320.rs | 15 + src/test/ui/issues/issue-2734.rs | 24 + src/test/ui/issues/issue-2735-2.rs | 27 + src/test/ui/issues/issue-2735-3.rs | 27 + src/test/ui/issues/issue-2735.rs | 24 + src/test/ui/issues/issue-27401-dropflag-reinit.rs | 27 + src/test/ui/issues/issue-2748-b.rs | 11 + src/test/ui/issues/issue-27639.rs | 11 + src/test/ui/issues/issue-27859.rs | 21 + src/test/ui/issues/issue-27890.rs | 7 + src/test/ui/issues/issue-27901.rs | 11 + src/test/ui/issues/issue-27949.rs | 41 + src/test/ui/issues/issue-27997.rs | 37 + src/test/ui/issues/issue-28181.rs | 6 + src/test/ui/issues/issue-28498-must-work-ex1.rs | 18 + src/test/ui/issues/issue-28498-must-work-ex2.rs | 20 + src/test/ui/issues/issue-28498-ugeh-ex1.rs | 27 + .../issues/issue-28498-ugeh-with-lifetime-param.rs | 38 + .../issues/issue-28498-ugeh-with-passed-to-fn.rs | 46 + .../ui/issues/issue-28498-ugeh-with-trait-bound.rs | 41 + src/test/ui/issues/issue-28550.rs | 16 + src/test/ui/issues/issue-28676.rs | 35 + src/test/ui/issues/issue-28777.rs | 21 + src/test/ui/issues/issue-28828.rs | 18 + src/test/ui/issues/issue-28839.rs | 15 + src/test/ui/issues/issue-2895.rs | 28 + src/test/ui/issues/issue-28950.rs | 22 + src/test/ui/issues/issue-28983.rs | 22 + src/test/ui/issues/issue-29053.rs | 12 + src/test/ui/issues/issue-29071-2.rs | 32 + src/test/ui/issues/issue-29092.rs | 26 + src/test/ui/issues/issue-29166.rs | 21 + src/test/ui/issues/issue-29227.rs | 142 + src/test/ui/issues/issue-2935.rs | 29 + src/test/ui/issues/issue-2936.rs | 31 + src/test/ui/issues/issue-29466.rs | 3603 ++++++++++++++++++++ src/test/ui/issues/issue-29485.rs | 18 + src/test/ui/issues/issue-29488.rs | 23 + src/test/ui/issues/issue-29522.rs | 17 + src/test/ui/issues/issue-29663.rs | 56 + src/test/ui/issues/issue-29668.rs | 16 + src/test/ui/issues/issue-29746.rs | 36 + src/test/ui/issues/issue-29844.rs | 24 + src/test/ui/issues/issue-2989.rs | 36 + src/test/ui/issues/issue-29914-2.rs | 6 + src/test/ui/issues/issue-29914-3.rs | 7 + src/test/ui/issues/issue-29914.rs | 10 + src/test/ui/issues/issue-29927-1.rs | 11 + src/test/ui/issues/issue-29927.rs | 11 + src/test/ui/issues/issue-29948.rs | 40 + src/test/ui/issues/issue-30018-nopanic.rs | 103 + src/test/ui/issues/issue-30018-panic.rs | 25 + src/test/ui/issues/issue-30081.rs | 15 + src/test/ui/issues/issue-3012-2.rs | 13 + src/test/ui/issues/issue-3026.rs | 13 + src/test/ui/issues/issue-3037.rs | 16 + src/test/ui/issues/issue-30371.rs | 10 + src/test/ui/issues/issue-30490.rs | 102 + src/test/ui/issues/issue-3052.rs | 13 + src/test/ui/issues/issue-30530.rs | 28 + src/test/ui/issues/issue-30615.rs | 5 + src/test/ui/issues/issue-30756.rs | 7 + src/test/ui/issues/issue-30891.rs | 10 + src/test/ui/issues/issue-3091.rs | 7 + src/test/ui/issues/issue-3109.rs | 4 + src/test/ui/issues/issue-3121.rs | 25 + src/test/ui/issues/issue-31267-additional.rs | 20 + src/test/ui/issues/issue-31267.rs | 14 + src/test/ui/issues/issue-31299.rs | 34 + src/test/ui/issues/issue-3136-b.rs | 8 + src/test/ui/issues/issue-31702.rs | 10 + src/test/ui/issues/issue-31776.rs | 57 + src/test/ui/issues/issue-32008.rs | 28 + src/test/ui/issues/issue-3211.rs | 7 + src/test/ui/issues/issue-3220.rs | 25 + src/test/ui/issues/issue-32292.rs | 9 + src/test/ui/issues/issue-32389.rs | 11 + src/test/ui/issues/issue-32518.rs | 13 + src/test/ui/issues/issue-32805.rs | 10 + src/test/ui/issues/issue-3290.rs | 8 + src/test/ui/issues/issue-32947.rs | 24 + src/test/ui/issues/issue-33096.rs | 18 + src/test/ui/issues/issue-33185.rs | 17 + src/test/ui/issues/issue-33187.rs | 18 + src/test/ui/issues/issue-33202.rs | 9 + src/test/ui/issues/issue-333.rs | 7 + src/test/ui/issues/issue-33387.rs | 32 + src/test/ui/issues/issue-33461.rs | 28 + src/test/ui/issues/issue-33498.rs | 11 + src/test/ui/issues/issue-33537.rs | 14 + src/test/ui/issues/issue-33687.rs | 17 + src/test/ui/issues/issue-33770.rs | 95 + src/test/ui/issues/issue-3389.rs | 26 + src/test/ui/issues/issue-33992.rs | 32 + src/test/ui/issues/issue-34053.rs | 30 + src/test/ui/issues/issue-34074.rs | 10 + src/test/ui/issues/issue-3429.rs | 8 + src/test/ui/issues/issue-34427.rs | 17 + src/test/ui/issues/issue-3447.rs | 33 + src/test/ui/issues/issue-34503.rs | 11 + src/test/ui/issues/issue-34569.rs | 17 + src/test/ui/issues/issue-34571.rs | 11 + src/test/ui/issues/issue-34784.rs | 19 + src/test/ui/issues/issue-34796.rs | 28 + src/test/ui/issues/issue-34798.rs | 25 + src/test/ui/issues/issue-34932.rs | 12 + src/test/ui/issues/issue-3500.rs | 10 + src/test/ui/issues/issue-35423.rs | 9 + src/test/ui/issues/issue-3556.rs | 36 + src/test/ui/issues/issue-3559.rs | 18 + src/test/ui/issues/issue-35600.rs | 16 + src/test/ui/issues/issue-3563-3.rs | 180 + src/test/ui/issues/issue-3574.rs | 14 + src/test/ui/issues/issue-35815.rs | 15 + src/test/ui/issues/issue-36023.rs | 24 + .../issues/issue-36036-associated-type-layout.rs | 27 + src/test/ui/issues/issue-36053.rs | 22 + .../ui/issues/issue-36139-normalize-closure-sig.rs | 19 + src/test/ui/issues/issue-36260.rs | 13 + src/test/ui/issues/issue-36278-prefix-nesting.rs | 19 + src/test/ui/issues/issue-36381.rs | 25 + src/test/ui/issues/issue-36401.rs | 16 + src/test/ui/issues/issue-36474.rs | 31 + src/test/ui/issues/issue-3656.rs | 30 + .../issues/issue-36744-bitcast-args-if-needed.rs | 23 + src/test/ui/issues/issue-36768.rs | 9 + src/test/ui/issues/issue-36786-resolve-call.rs | 8 + src/test/ui/issues/issue-36792.rs | 7 + src/test/ui/issues/issue-36816.rs | 7 + src/test/ui/issues/issue-3683.rs | 18 + src/test/ui/issues/issue-36856.rs | 15 + src/test/ui/issues/issue-36936.rs | 26 + src/test/ui/issues/issue-36954.rs | 8 + src/test/ui/issues/issue-3702.rs | 13 + src/test/ui/issues/issue-37109.rs | 16 + src/test/ui/issues/issue-37175.rs | 5 + src/test/ui/issues/issue-37222.rs | 17 + src/test/ui/issues/issue-37291/auxiliary/lib.rs | 42 + src/test/ui/issues/issue-37291/main.rs | 21 + src/test/ui/issues/issue-3743.rs | 55 + src/test/ui/issues/issue-3753.rs | 32 + src/test/ui/issues/issue-37686.rs | 7 + src/test/ui/issues/issue-3794.rs | 32 + src/test/ui/issues/issue-37991.rs | 17 + src/test/ui/issues/issue-38002.rs | 35 + src/test/ui/issues/issue-38033.rs | 79 + src/test/ui/issues/issue-38074.rs | 20 + src/test/ui/issues/issue-38091.rs | 20 + src/test/ui/issues/issue-38190.rs | 15 + src/test/ui/issues/issue-38226.rs | 15 + src/test/ui/issues/issue-38437.rs | 46 + src/test/ui/issues/issue-3847.rs | 13 + src/test/ui/issues/issue-38556.rs | 13 + src/test/ui/issues/issue-38763.rs | 12 + src/test/ui/issues/issue-3878.rs | 10 + src/test/ui/issues/issue-38942.rs | 17 + src/test/ui/issues/issue-3895.rs | 11 + src/test/ui/issues/issue-38987.rs | 4 + src/test/ui/issues/issue-3904.rs | 25 + src/test/ui/issues/issue-39292.rs | 17 + src/test/ui/issues/issue-3935.rs | 13 + src/test/ui/issues/issue-39367.rs | 39 + src/test/ui/issues/issue-39548.rs | 6 + src/test/ui/issues/issue-39709.rs | 5 + src/test/ui/issues/issue-39720.rs | 26 + src/test/ui/issues/issue-39720.stderr | 16 + src/test/ui/issues/issue-3979-generics.rs | 36 + src/test/ui/issues/issue-3979-xcrate.rs | 25 + src/test/ui/issues/issue-3979.rs | 34 + src/test/ui/issues/issue-39808.rs | 17 + src/test/ui/issues/issue-39823.rs | 25 + src/test/ui/issues/issue-39827.rs | 34 + src/test/ui/issues/issue-40003.rs | 178 + src/test/ui/issues/issue-40085.rs | 13 + src/test/ui/issues/issue-40235.rs | 8 + src/test/ui/issues/issue-40408.rs | 7 + src/test/ui/issues/issue-40469.rs | 9 + src/test/ui/issues/issue-40770.rs | 11 + src/test/ui/issues/issue-40847.rs | 17 + src/test/ui/issues/issue-40883.rs | 93 + src/test/ui/issues/issue-40951.rs | 12 + src/test/ui/issues/issue-41053.rs | 21 + src/test/ui/issues/issue-4107.rs | 26 + src/test/ui/issues/issue-41213.rs | 24 + src/test/ui/issues/issue-41479.rs | 9 + src/test/ui/issues/issue-41498.rs | 17 + src/test/ui/issues/issue-41604.rs | 11 + src/test/ui/issues/issue-41677.rs | 28 + src/test/ui/issues/issue-41696.rs | 54 + src/test/ui/issues/issue-41744.rs | 7 + src/test/ui/issues/issue-41803.rs | 21 + src/test/ui/issues/issue-41849-variance-req.rs | 35 + src/test/ui/issues/issue-41888.rs | 34 + src/test/ui/issues/issue-42007.rs | 11 + src/test/ui/issues/issue-4208.rs | 12 + src/test/ui/issues/issue-42148.rs | 6 + src/test/ui/issues/issue-42210.rs | 20 + src/test/ui/issues/issue-4228.rs | 16 + src/test/ui/issues/issue-42453.rs | 10 + src/test/ui/issues/issue-42463.rs | 32 + src/test/ui/issues/issue-4252.rs | 33 + src/test/ui/issues/issue-42552.rs | 31 + src/test/ui/issues/issue-42679.rs | 22 + src/test/ui/issues/issue-42747.rs | 46 + src/test/ui/issues/issue-43132.rs | 65 + src/test/ui/issues/issue-43205.rs | 5 + src/test/ui/issues/issue-43291.rs | 9 + src/test/ui/issues/issue-4333.rs | 10 + src/test/ui/issues/issue-43692.rs | 5 + src/test/ui/issues/issue-43853.rs | 17 + src/test/ui/issues/issue-4387.rs | 6 + src/test/ui/issues/issue-43910.rs | 7 + src/test/ui/issues/issue-43923.rs | 12 + src/test/ui/issues/issue-4401.rs | 7 + src/test/ui/issues/issue-44333.rs | 20 + src/test/ui/issues/issue-4446.rs | 15 + src/test/ui/issues/issue-4448.rs | 16 + src/test/ui/issues/issue-45124.rs | 18 + src/test/ui/issues/issue-45152.rs | 24 + src/test/ui/issues/issue-4541.rs | 23 + src/test/ui/issues/issue-4542.rs | 13 + src/test/ui/issues/issue-4545.rs | 7 + src/test/ui/issues/issue-45510.rs | 32 + src/test/ui/issues/issue-45731.rs | 26 + src/test/ui/issues/issue-46069.rs | 23 + src/test/ui/issues/issue-46095.rs | 30 + src/test/ui/issues/issue-46519.rs | 28 + src/test/ui/issues/issue-46553.rs | 23 + src/test/ui/issues/issue-46845.rs | 32 + src/test/ui/issues/issue-46855.rs | 24 + .../ui/issues/issue-46920-byte-array-patterns.rs | 28 + src/test/ui/issues/issue-47139-1.rs | 78 + src/test/ui/issues/issue-47139-2.rs | 66 + src/test/ui/issues/issue-4734.rs | 37 + src/test/ui/issues/issue-4735.rs | 19 + src/test/ui/issues/issue-47364.rs | 59 + src/test/ui/issues/issue-4759-1.rs | 4 + src/test/ui/issues/issue-4759.rs | 20 + src/test/ui/issues/issue-47638.rs | 10 + src/test/ui/issues/issue-48006.rs | 15 + src/test/ui/issues/issue-48159.rs | 27 + src/test/ui/issues/issue-48508-aux.rs | 7 + src/test/ui/issues/issue-48508.rs | 19 + src/test/ui/issues/issue-4865-1.rs | 33 + src/test/ui/issues/issue-4865-2.rs | 24 + src/test/ui/issues/issue-4865-3.rs | 17 + src/test/ui/issues/issue-4875.rs | 15 + src/test/ui/issues/issue-48962.rs | 34 + src/test/ui/issues/issue-48984.rs | 9 + src/test/ui/issues/issue-49298.rs | 42 + ...on-shorthand-field-patterns-in-pattern-macro.rs | 16 + src/test/ui/issues/issue-49632.rs | 8 + src/test/ui/issues/issue-49685.rs | 13 + src/test/ui/issues/issue-49854.rs | 9 + src/test/ui/issues/issue-49955-2.rs | 19 + src/test/ui/issues/issue-49955.rs | 20 + src/test/ui/issues/issue-49973.rs | 11 + .../issue-5008-borrowed-traitobject-method-call.rs | 34 + src/test/ui/issues/issue-50415.rs | 18 + src/test/ui/issues/issue-50442.rs | 13 + src/test/ui/issues/issue-5060.rs | 16 + src/test/ui/issues/issue-50689.rs | 9 + src/test/ui/issues/issue-50731.rs | 6 + src/test/ui/issues/issue-50811.rs | 56 + .../auxiliary/lib.rs | 14 + .../issues/issue-50865-private-impl-trait/main.rs | 16 + src/test/ui/issues/issue-51185.rs | 8 + src/test/ui/issues/issue-51345.rs | 8 + src/test/ui/issues/issue-51582.rs | 18 + src/test/ui/issues/issue-51907.rs | 17 + src/test/ui/issues/issue-5192.rs | 41 + .../ui/issues/issue-52140/auxiliary/some_crate.rs | 5 + src/test/ui/issues/issue-52140/main.rs | 13 + .../ui/issues/issue-52141/auxiliary/some_crate.rs | 5 + src/test/ui/issues/issue-52141/main.rs | 16 + src/test/ui/issues/issue-52169.rs | 14 + src/test/ui/issues/issue-5239-2.rs | 9 + src/test/ui/issues/issue-5243.rs | 17 + src/test/ui/issues/issue-52557.rs | 30 + src/test/ui/issues/issue-52705/auxiliary/png2.rs | 3 + src/test/ui/issues/issue-52705/main.rs | 15 + src/test/ui/issues/issue-5280.rs | 18 + src/test/ui/issues/issue-5315.rs | 9 + .../issues/issue-5321-immediates-with-bare-self.rs | 15 + src/test/ui/issues/issue-53333.rs | 9 + src/test/ui/issues/issue-53728.rs | 19 + src/test/ui/issues/issue-53843.rs | 26 + .../issue-54462-mutable-noalias-correctness.rs | 25 + src/test/ui/issues/issue-54467.rs | 46 + src/test/ui/issues/issue-54477-reduced-2.rs | 26 + src/test/ui/issues/issue-54696.rs | 8 + src/test/ui/issues/issue-5518.rs | 8 + src/test/ui/issues/issue-5521.rs | 17 + src/test/ui/issues/issue-5530.rs | 40 + src/test/ui/issues/issue-55376.rs | 16 + src/test/ui/issues/issue-55380.rs | 28 + src/test/ui/issues/issue-5550.rs | 9 + src/test/ui/issues/issue-5554.rs | 29 + src/test/ui/issues/issue-56237.rs | 13 + src/test/ui/issues/issue-5666.rs | 27 + src/test/ui/issues/issue-5688.rs | 20 + src/test/ui/issues/issue-5708.rs | 55 + src/test/ui/issues/issue-5718.rs | 26 + src/test/ui/issues/issue-5741.rs | 9 + src/test/ui/issues/issue-5791.rs | 12 + src/test/ui/issues/issue-58212.rs | 16 + .../ui/issues/issue-58435-ice-with-assoc-const.rs | 18 + src/test/ui/issues/issue-58463.rs | 8 + src/test/ui/issues/issue-5917.rs | 9 + src/test/ui/issues/issue-5988.rs | 24 + src/test/ui/issues/issue-5997.rs | 15 + src/test/ui/issues/issue-6117.rs | 12 + src/test/ui/issues/issue-6128.rs | 24 + src/test/ui/issues/issue-6130.rs | 10 + src/test/ui/issues/issue-6153.rs | 13 + src/test/ui/issues/issue-6157.rs | 23 + src/test/ui/issues/issue-61696.rs | 66 + src/test/ui/issues/issue-61894.rs | 21 + src/test/ui/issues/issue-6318.rs | 22 + src/test/ui/issues/issue-6334.rs | 46 + src/test/ui/issues/issue-6344-let.rs | 15 + src/test/ui/issues/issue-6344-match.rs | 18 + src/test/ui/issues/issue-6449.rs | 44 + src/test/ui/issues/issue-6892.rs | 58 + src/test/ui/issues/issue-6919.rs | 12 + src/test/ui/issues/issue-7012.rs | 22 + src/test/ui/issues/issue-7178.rs | 10 + src/test/ui/issues/issue-7222.rs | 12 + src/test/ui/issues/issue-7344.rs | 22 + src/test/ui/issues/issue-7519-match-unit-in-arg.rs | 12 + src/test/ui/issues/issue-7563.rs | 28 + src/test/ui/issues/issue-7575.rs | 17 + src/test/ui/issues/issue-7660.rs | 18 + src/test/ui/issues/issue-7663.rs | 32 + src/test/ui/issues/issue-7784.rs | 31 + src/test/ui/issues/issue-7899.rs | 11 + src/test/ui/issues/issue-7911.rs | 37 + src/test/ui/issues/issue-8044.rs | 11 + src/test/ui/issues/issue-8248.rs | 15 + src/test/ui/issues/issue-8249.rs | 20 + src/test/ui/issues/issue-8259.rs | 12 + src/test/ui/issues/issue-8351-1.rs | 16 + src/test/ui/issues/issue-8351-2.rs | 16 + src/test/ui/issues/issue-8391.rs | 9 + src/test/ui/issues/issue-8401.rs | 8 + src/test/ui/issues/issue-8460.rs | 51 + src/test/ui/issues/issue-8498.rs | 27 + src/test/ui/issues/issue-8506.rs | 14 + src/test/ui/issues/issue-868.rs | 18 + src/test/ui/issues/issue-8709.rs | 14 + src/test/ui/issues/issue-8783.rs | 24 + src/test/ui/issues/issue-8827.rs | 53 + src/test/ui/issues/issue-8851.rs | 30 + src/test/ui/issues/issue-8860.rs | 49 + src/test/ui/issues/issue-8898.rs | 18 + src/test/ui/issues/issue-9047.rs | 14 + src/test/ui/issues/issue-9123.rs | 8 + src/test/ui/issues/issue-9129.rs | 35 + src/test/ui/issues/issue-9155.rs | 12 + src/test/ui/issues/issue-9188.rs | 11 + src/test/ui/issues/issue-9259.rs | 16 + src/test/ui/issues/issue-9382.rs | 41 + .../ui/issues/issue-9394-inherited-trait-calls.rs | 62 + src/test/ui/issues/issue-9396.rs | 24 + src/test/ui/issues/issue-9446.rs | 30 + src/test/ui/issues/issue-9737.rs | 10 + src/test/ui/issues/issue-979.rs | 29 + src/test/ui/issues/issue-9837.rs | 11 + src/test/ui/issues/issue-9906.rs | 11 + src/test/ui/issues/issue-9918.rs | 5 + src/test/ui/issues/issue-9942.rs | 6 + src/test/ui/issues/issue-9951.rs | 21 + src/test/ui/issues/issue-9968.rs | 13 + src/test/ui/istr.rs | 53 + src/test/ui/item-name-overload.rs | 17 + .../into-iterator-type-inference-shift.rs | 36 + .../ui/iterators/iter-cloned-type-inference.rs | 16 + src/test/ui/iterators/iter-range.rs | 14 + src/test/ui/iterators/iter-step-overflow-debug.rs | 21 + src/test/ui/iterators/iter-step-overflow-ndebug.rs | 12 + src/test/ui/iterators/iter-sum-overflow-debug.rs | 27 + src/test/ui/iterators/iter-sum-overflow-ndebug.rs | 14 + .../iterators/iter-sum-overflow-overflow-checks.rs | 27 + src/test/ui/iterators/iter-zip.rs | 103 + src/test/ui/keyword-changes-2012-07-31.rs | 20 + src/test/ui/kindck-implicit-close-over-mut-var.rs | 49 + src/test/ui/kinds-in-metadata.rs | 17 + src/test/ui/lambda-infer-unresolved.rs | 15 + src/test/ui/lambda-var-hygiene.rs | 12 + src/test/ui/large-records.rs | 38 + src/test/ui/last-use-in-block.rs | 21 + src/test/ui/last-use-in-cap-clause.rs | 17 + src/test/ui/last-use-is-capture.rs | 15 + src/test/ui/lazy-and-or.rs | 12 + src/test/ui/lazy-init.rs | 8 + src/test/ui/leak-unique-as-tydesc.rs | 8 + src/test/ui/lex-bare-cr-nondoc-comment.rs | 9 + ...crlf-line-endings-string-literal-doc-comment.rs | 41 + src/test/ui/lexical-scoping.rs | 19 + src/test/ui/lib-defaults.rs | 17 + src/test/ui/link-cfg-works.rs | 13 + src/test/ui/link-section.rs | 37 + src/test/ui/linkage1.rs | 32 + src/test/ui/lint-cap.rs | 8 + src/test/ui/lint-dead-code-associated-type.rs | 19 + src/test/ui/lint-dead-code-variant.rs | 14 + .../ui/lint-expr-stmt-attrs-for-early-lints.rs | 14 + src/test/ui/lint-unknown-lints-at-crate-level.rs | 7 + src/test/ui/list.rs | 10 + src/test/ui/liveness-assign-imm-local-after-ret.rs | 16 + src/test/ui/llvm-pr32379.rs | 14 + src/test/ui/log-err-phi.rs | 7 + .../ui/log-knows-the-names-of-variants-in-std.rs | 27 + src/test/ui/log-knows-the-names-of-variants.rs | 21 + src/test/ui/log-poly.rs | 13 + src/test/ui/logging-only-prints-once.rs | 28 + src/test/ui/logging_before_rt_started.rs | 12 + src/test/ui/long-while.rs | 12 + src/test/ui/lto-many-codegen-units.rs | 6 + src/test/ui/lto-still-runs-thread-dtors.rs | 32 + src/test/ui/lub-glb-with-unbound-infer-var.rs | 15 + src/test/ui/macro-quote-cond.rs | 48 + src/test/ui/macro-quote-test.rs | 12 + src/test/ui/macros/assert-eq-macro-success.rs | 13 + src/test/ui/macros/assert-eq-macro-unsized.rs | 4 + src/test/ui/macros/assert-ne-macro-success.rs | 13 + src/test/ui/macros/assert-ne-macro-unsized.rs | 4 + .../ui/macros/auxiliary/macro-comma-support.rs | 1 + .../macros/auxiliary/macro-include-items-expr.rs | 3 + .../macros/auxiliary/macro-include-items-item.rs | 3 + .../ui/macros/auxiliary/macro_crate_def_only.rs | 4 + .../macros/auxiliary/macro_export_inner_module.rs | 6 + src/test/ui/macros/auxiliary/macro_with_super_1.rs | 16 + src/test/ui/macros/auxiliary/two_macros-rpass.rs | 5 + src/test/ui/macros/auxiliary/use-macro-self.rs | 6 + src/test/ui/macros/colorful-write-macros.rs | 34 + src/test/ui/macros/conditional-debug-macro-on.rs | 8 + src/test/ui/macros/die-macro.rs | 16 + src/test/ui/macros/issue-25274.rs | 18 + .../log_syntax-trace_macros-macro-locations.rs | 22 + .../log_syntax-trace_macros-macro-locations.stdout | 3 + src/test/ui/macros/macro-2.rs | 12 + src/test/ui/macros/macro-as-fn-body.rs | 33 + src/test/ui/macros/macro-attribute-expansion.rs | 16 + src/test/ui/macros/macro-attributes.rs | 23 + src/test/ui/macros/macro-block-nonterminal.rs | 11 + src/test/ui/macros/macro-crate-def-only.rs | 10 + .../ui/macros/macro-crate-nonterminal-renamed.rs | 10 + src/test/ui/macros/macro-crate-nonterminal.rs | 10 + src/test/ui/macros/macro-crate-use.rs | 17 + src/test/ui/macros/macro-deep_expansion.rs | 17 + src/test/ui/macros/macro-delimiter-significance.rs | 4 + src/test/ui/macros/macro-doc-comments.rs | 26 + src/test/ui/macros/macro-doc-escapes.rs | 16 + src/test/ui/macros/macro-doc-raw-str-hashes.rs | 30 + src/test/ui/macros/macro-export-inner-module.rs | 9 + src/test/ui/macros/macro-first-set.rs | 277 ++ src/test/ui/macros/macro-followed-by-seq.rs | 14 + src/test/ui/macros/macro-include-items.rs | 13 + src/test/ui/macros/macro-interpolation.rs | 21 + ...ro-invocation-in-count-expr-fixed-array-type.rs | 10 + .../ui/macros/macro-lifetime-used-with-bound.rs | 15 + .../ui/macros/macro-lifetime-used-with-labels.rs | 36 + .../macros/macro-lifetime-used-with-labels.stderr | 11 + .../ui/macros/macro-lifetime-used-with-static.rs | 14 + src/test/ui/macros/macro-lifetime.rs | 14 + src/test/ui/macros/macro-literal.rs | 133 + src/test/ui/macros/macro-meta-items.rs | 31 + src/test/ui/macros/macro-method-issue-4621.rs | 10 + src/test/ui/macros/macro-multiple-items.rs | 16 + src/test/ui/macros/macro-named-default.rs | 18 + .../macros/macro-nested_definition_issue-31946.rs | 9 + src/test/ui/macros/macro-nested_expr.rs | 22 + src/test/ui/macros/macro-nested_stmt_macros.rs | 23 + src/test/ui/macros/macro-nt-list.rs | 21 + src/test/ui/macros/macro-of-higher-order.rs | 22 + src/test/ui/macros/macro-pat-follow.rs | 31 + src/test/ui/macros/macro-pat-neg-lit.rs | 25 + src/test/ui/macros/macro-pat.rs | 65 + src/test/ui/macros/macro-path.rs | 18 + src/test/ui/macros/macro-pub-matcher.rs | 118 + src/test/ui/macros/macro-seq-followed-by-seq.rs | 17 + src/test/ui/macros/macro-stmt.rs | 31 + .../ui/macros/macro-stmt_macro_in_expr_macro.rs | 21 + src/test/ui/macros/macro-tt-followed-by-seq.rs | 27 + src/test/ui/macros/macro-use-all-and-none.rs | 13 + src/test/ui/macros/macro-use-all-and-none.stderr | 12 + src/test/ui/macros/macro-use-all.rs | 10 + src/test/ui/macros/macro-use-both.rs | 10 + src/test/ui/macros/macro-use-one.rs | 9 + src/test/ui/macros/macro-with-attrs1.rs | 13 + src/test/ui/macros/macro-with-attrs2.rs | 11 + .../macros/macro-with-braces-in-expr-position.rs | 22 + src/test/ui/macros/macro_with_super_2.rs | 13 + src/test/ui/macros/meta-variable-misuse.rs | 34 + src/test/ui/macros/parse-complex-macro-invoc-op.rs | 42 + src/test/ui/macros/paths-in-macro-invocations.rs | 36 + src/test/ui/macros/pub-item-inside-macro.rs | 18 + src/test/ui/macros/pub-method-inside-macro.rs | 22 + src/test/ui/macros/semi-after-macro-ty.rs | 8 + src/test/ui/macros/stmt_expr_attr_macro_parse.rs | 23 + src/test/ui/macros/syntax-extension-cfg.rs | 24 + .../includeme.fragment | 7 + .../ui/macros/syntax-extension-source-utils.rs | 37 + src/test/ui/macros/try-macro.rs | 48 + src/test/ui/macros/two-macro-use.rs | 11 + src/test/ui/macros/type-macros-hlist.rs | 78 + src/test/ui/macros/type-macros-simple.rs | 30 + .../macros/typeck-macro-interaction-issue-8852.rs | 30 + src/test/ui/macros/use-macro-self.rs | 12 + src/test/ui/max-min-classes.rs | 32 + src/test/ui/methods/auxiliary/method_self_arg1.rs | 37 + src/test/ui/methods/auxiliary/method_self_arg2.rs | 54 + .../method-argument-inference-associated-type.rs | 28 + .../method-early-bound-lifetimes-on-self.rs | 31 + .../method-mut-self-modifies-mut-slice-lvalue.rs | 44 + .../methods/method-normalize-bounds-issue-20604.rs | 61 + .../methods/method-probe-no-guessing-dyn-trait.rs | 60 + src/test/ui/methods/method-projection.rs | 70 + .../ui/methods/method-recursive-blanket-impl.rs | 41 + src/test/ui/methods/method-self-arg-aux1.rs | 20 + src/test/ui/methods/method-self-arg-aux2.rs | 24 + src/test/ui/methods/method-self-arg-trait.rs | 69 + src/test/ui/methods/method-self-arg.rs | 48 + .../methods/method-two-trait-defer-resolution-1.rs | 37 + .../methods/method-two-trait-defer-resolution-2.rs | 48 + ...od-two-traits-distinguished-via-where-clause.rs | 27 + src/test/ui/methods/method-where-clause.rs | 34 + src/test/ui/mid-path-type-params.rs | 37 + src/test/ui/minmax-stability-issue-23687.rs | 64 + src/test/ui/mir/auxiliary/mir_external_refs.rs | 17 + src/test/ui/mir/mir-inlining/ice-issue-45493.rs | 17 + src/test/ui/mir/mir-inlining/ice-issue-45885.rs | 29 + .../mir-inlining/no-trait-method-issue-40473.rs | 16 + src/test/ui/mir/mir-typeck-normalize-fn-sig.rs | 30 + src/test/ui/mir/mir_adt_construction.rs | 92 + src/test/ui/mir/mir_ascription_coercion.rs | 10 + src/test/ui/mir/mir_augmented_assignments.rs | 160 + src/test/ui/mir/mir_autoderef.rs | 28 + src/test/ui/mir/mir_boxing.rs | 10 + src/test/ui/mir/mir_build_match_comparisons.rs | 59 + src/test/ui/mir/mir_call_with_associated_type.rs | 16 + src/test/ui/mir/mir_calls_to_shims.rs | 49 + src/test/ui/mir/mir_cast_fn_ret.rs | 21 + src/test/ui/mir/mir_codegen_array.rs | 11 + src/test/ui/mir/mir_codegen_array_2.rs | 9 + src/test/ui/mir/mir_codegen_call_converging.rs | 17 + src/test/ui/mir/mir_codegen_calls.rs | 191 ++ src/test/ui/mir/mir_codegen_calls_variadic.rs | 22 + src/test/ui/mir/mir_codegen_critical_edge.rs | 44 + src/test/ui/mir/mir_codegen_spike1.rs | 12 + src/test/ui/mir/mir_codegen_switch.rs | 35 + src/test/ui/mir/mir_codegen_switchint.rs | 12 + src/test/ui/mir/mir_coercion_casts.rs | 10 + src/test/ui/mir/mir_coercions.rs | 71 + src/test/ui/mir/mir_constval_adts.rs | 34 + src/test/ui/mir/mir_drop_order.rs | 48 + src/test/ui/mir/mir_early_return_scope.rs | 29 + src/test/ui/mir/mir_fat_ptr.rs | 52 + src/test/ui/mir/mir_fat_ptr_drop.rs | 32 + src/test/ui/mir/mir_heavy_promoted.rs | 11 + src/test/ui/mir/mir_match_arm_guard.rs | 16 + src/test/ui/mir/mir_match_test.rs | 83 + src/test/ui/mir/mir_misc_casts.rs | 320 ++ src/test/ui/mir/mir_overflow_off.rs | 17 + src/test/ui/mir/mir_raw_fat_ptr.rs | 158 + src/test/ui/mir/mir_refs_correct.rs | 209 ++ src/test/ui/mir/mir_small_agg_arg.rs | 8 + src/test/ui/mir/mir_static_subtype.rs | 9 + src/test/ui/mir/mir_struct_with_assoc_ty.rs | 29 + src/test/ui/mir/mir_temp_promotions.rs | 10 + src/test/ui/mir/mir_void_return.rs | 12 + src/test/ui/mir/mir_void_return_2.rs | 10 + src/test/ui/modules/auxiliary/two_macros_2.rs | 3 + src/test/ui/modules/mod-inside-fn.rs | 13 + src/test/ui/modules/mod-view-items.rs | 14 + src/test/ui/modules/mod_dir_implicit.rs | 8 + .../mod_dir_implicit_aux/compiletest-ignore-dir | 0 src/test/ui/modules/mod_dir_implicit_aux/mod.rs | 2 + src/test/ui/modules/mod_dir_path.rs | 23 + src/test/ui/modules/mod_dir_path2.rs | 12 + src/test/ui/modules/mod_dir_path3.rs | 11 + src/test/ui/modules/mod_dir_path_multi.rs | 17 + src/test/ui/modules/mod_dir_recursive.rs | 14 + src/test/ui/modules/mod_dir_simple.rs | 10 + .../modules/mod_dir_simple/compiletest-ignore-dir | 0 .../ui/modules/mod_dir_simple/load_another_mod.rs | 3 + src/test/ui/modules/mod_dir_simple/test.rs | 2 + src/test/ui/modules/mod_file.rs | 10 + src/test/ui/modules/mod_file_aux.rs | 4 + src/test/ui/modules/mod_file_with_path_attr.rs | 11 + .../compiletest-ignore-dir | 0 .../float-template/inst_f32.rs | 3 + .../float-template/inst_f64.rs | 3 + .../float-template/inst_float.rs | 3 + src/test/ui/monad.rs | 48 + src/test/ui/monomorphize-abi-alignment.rs | 34 + .../monomorphized-callees-with-ty-params-3314.rs | 32 + src/test/ui/moves/move-1-unique.rs | 25 + src/test/ui/moves/move-2-unique.rs | 11 + src/test/ui/moves/move-2.rs | 7 + src/test/ui/moves/move-3-unique.rs | 25 + src/test/ui/moves/move-4-unique.rs | 19 + src/test/ui/moves/move-4.rs | 19 + src/test/ui/moves/move-arg-2-unique.rs | 13 + src/test/ui/moves/move-arg-2.rs | 13 + src/test/ui/moves/move-arg.rs | 5 + src/test/ui/moves/move-nullary-fn.rs | 13 + src/test/ui/moves/move-out-of-field.rs | 27 + src/test/ui/moves/move-scalar.rs | 10 + .../ui/moves/moves-based-on-type-capture-clause.rs | 12 + src/test/ui/mpsc_stress.rs | 164 + src/test/ui/msvc-data-only.rs | 8 + src/test/ui/multi-panic.rs | 38 + src/test/ui/multibyte.rs | 7 + ...ultidispatch-conditional-impl-not-considered.rs | 24 + src/test/ui/multidispatch1.rs | 33 + src/test/ui/multidispatch2.rs | 39 + src/test/ui/multiline-comment.rs | 7 + src/test/ui/multiple-reprs.rs | 82 + src/test/ui/mut-function-arguments.rs | 21 + src/test/ui/mut-vstore-expr.rs | 6 + src/test/ui/mutual-recursion-group.rs | 16 + src/test/ui/native-print-no-runtime.rs | 9 + src/test/ui/negative.rs | 8 + src/test/ui/nested-block-comment.rs | 12 + src/test/ui/nested-class.rs | 25 + src/test/ui/nested-function-names-issue-8587.rs | 42 + src/test/ui/nested_item_main.rs | 10 + src/test/ui/never-result.rs | 20 + src/test/ui/never-type-rvalues.rs | 38 + src/test/ui/never_coercions.rs | 12 + src/test/ui/new-box-syntax.rs | 28 + src/test/ui/new-box.rs | 32 + src/test/ui/new-impl-syntax.rs | 29 + src/test/ui/new-import-syntax.rs | 5 + src/test/ui/new-style-constants.rs | 7 + src/test/ui/new-unicode-escapes.rs | 14 + src/test/ui/new-unsafe-pointers.rs | 7 + src/test/ui/newlambdas-ret-infer.rs | 12 + src/test/ui/newlambdas-ret-infer2.rs | 12 + src/test/ui/newlambdas.rs | 14 + src/test/ui/newtype-polymorphic.rs | 27 + src/test/ui/newtype-temporary.rs | 12 + src/test/ui/newtype.rs | 23 + src/test/ui/nil-decl-in-foreign.rs | 14 + src/test/ui/nll/issue-47153-generic-const.rs | 18 + src/test/ui/nll/issue-47589.rs | 23 + src/test/ui/nll/issue-48623-closure.rs | 16 + src/test/ui/nll/issue-48623-generator.rs | 18 + src/test/ui/nll/issue-50343.rs | 8 + src/test/ui/nll/issue-50461-used-mut-from-moves.rs | 16 + src/test/ui/nll/issue-53123-raw-pointer-cast.rs | 26 + src/test/ui/nll/mutating_references.rs | 24 + src/test/ui/nll/process_or_insert_default.rs | 27 + src/test/ui/nll/rc-loop.rs | 28 + src/test/ui/no-core-1.rs | 15 + src/test/ui/no-core-2.rs | 20 + src/test/ui/no-landing-pads.rs | 23 + src/test/ui/no-std-1.rs | 10 + src/test/ui/no-std-2.rs | 10 + src/test/ui/no-std-3.rs | 17 + src/test/ui/no-stdio.rs | 120 + src/test/ui/non-built-in-quote.rs | 8 + src/test/ui/non-legacy-modes.rs | 22 + src/test/ui/non_modrs_mods/foors_mod.rs | 10 + .../foors_mod/compiletest-ignore-dir | 0 .../ui/non_modrs_mods/foors_mod/inline/somename.rs | 3 + .../ui/non_modrs_mods/foors_mod/inner_foors_mod.rs | 3 + .../foors_mod/inner_foors_mod/innest.rs | 3 + .../foors_mod/inner_modrs_mod/innest.rs | 3 + .../foors_mod/inner_modrs_mod/mod.rs | 3 + .../modrs_mod/compiletest-ignore-dir | 0 .../ui/non_modrs_mods/modrs_mod/inline/somename.rs | 3 + .../ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs | 3 + .../modrs_mod/inner_foors_mod/innest.rs | 3 + .../modrs_mod/inner_modrs_mod/innest.rs | 3 + .../modrs_mod/inner_modrs_mod/mod.rs | 3 + src/test/ui/non_modrs_mods/modrs_mod/mod.rs | 8 + src/test/ui/non_modrs_mods/non_modrs_mods.rs | 16 + .../some_crazy_attr_mod_dir/arbitrary_name.rs | 3 + .../some_crazy_attr_mod_dir/compiletest-ignore-dir | 0 .../inner_modrs_mod/innest.rs | 3 + .../some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs | 3 + src/test/ui/nul-characters.rs | 36 + src/test/ui/nullable-pointer-ffi-compat.rs | 28 + src/test/ui/nullable-pointer-iotareduction.rs | 73 + src/test/ui/nullable-pointer-size.rs | 35 + src/test/ui/numbers-arithmetic/arith-0.rs | 8 + src/test/ui/numbers-arithmetic/arith-1.rs | 24 + src/test/ui/numbers-arithmetic/arith-2.rs | 9 + src/test/ui/numbers-arithmetic/arith-unsigned.rs | 26 + src/test/ui/numbers-arithmetic/div-mod.rs | 19 + .../float-int-invalid-const-cast.rs | 53 + .../numbers-arithmetic/float-literal-inference.rs | 13 + src/test/ui/numbers-arithmetic/float-nan.rs | 83 + src/test/ui/numbers-arithmetic/float-signature.rs | 9 + src/test/ui/numbers-arithmetic/float.rs | 9 + src/test/ui/numbers-arithmetic/float2.rs | 26 + src/test/ui/numbers-arithmetic/float_math.rs | 21 + src/test/ui/numbers-arithmetic/floatlits.rs | 12 + src/test/ui/numbers-arithmetic/i128-ffi.rs | 31 + src/test/ui/numbers-arithmetic/i128.rs | 110 + src/test/ui/numbers-arithmetic/i32-sub.rs | 6 + src/test/ui/numbers-arithmetic/i8-incr.rs | 12 + src/test/ui/numbers-arithmetic/int-abs-overflow.rs | 13 + src/test/ui/numbers-arithmetic/int.rs | 7 + .../ui/numbers-arithmetic/integer-literal-radix.rs | 19 + .../integer-literal-suffix-inference-2.rs | 9 + .../integer-literal-suffix-inference-3.rs | 4 + .../integer-literal-suffix-inference.rs | 60 + .../next-power-of-two-overflow-debug.rs | 27 + .../next-power-of-two-overflow-ndebug.rs | 14 + src/test/ui/numbers-arithmetic/num-wrapping.rs | 447 +++ .../numeric-method-autoexport.rs | 25 + .../ui/numbers-arithmetic/promoted_overflow_opt.rs | 9 + .../numbers-arithmetic/saturating-float-casts.rs | 135 + src/test/ui/numbers-arithmetic/shift-near-oflo.rs | 100 + .../ui/numbers-arithmetic/shift-various-types.rs | 48 + src/test/ui/numbers-arithmetic/shift.rs | 76 + .../numbers-arithmetic/signed-shift-const-eval.rs | 8 + src/test/ui/numbers-arithmetic/u128-as-f32.rs | 49 + src/test/ui/numbers-arithmetic/u128.rs | 121 + src/test/ui/numbers-arithmetic/u32-decr.rs | 10 + src/test/ui/numbers-arithmetic/u8-incr-decr.rs | 19 + src/test/ui/numbers-arithmetic/u8-incr.rs | 15 + src/test/ui/numbers-arithmetic/uint.rs | 7 + .../object-lifetime-default-default-to-static.rs | 35 + .../ui/object-lifetime-default-from-rptr-box.rs | 33 + .../ui/object-lifetime-default-from-rptr-mut.rs | 36 + src/test/ui/object-lifetime-default-from-rptr.rs | 42 + src/test/ui/object-method-numbering.rs | 28 + src/test/ui/objects-coerce-freeze-borrored.rs | 40 + ...ects-owned-object-borrowed-method-headerless.rs | 33 + src/test/ui/objects-owned-object-owned-method.rs | 25 + src/test/ui/once-move-out-on-heap.rs | 18 + src/test/ui/one-tuple.rs | 15 + src/test/ui/op-assign-builtins-by-ref.rs | 76 + src/test/ui/opeq.rs | 17 + src/test/ui/operator-associativity.rs | 4 + src/test/ui/operator-multidispatch.rs | 36 + src/test/ui/operator-overloading.rs | 81 + src/test/ui/optimization-fuel-0.rs | 16 + src/test/ui/optimization-fuel-0.stderr | 1 + src/test/ui/optimization-fuel-1.rs | 17 + src/test/ui/optimization-fuel-1.stderr | 1 + src/test/ui/option-ext.rs | 10 + src/test/ui/option-unwrap.rs | 32 + src/test/ui/out-of-stack.rs | 90 + src/test/ui/out-pointer-aliasing.rs | 23 + src/test/ui/output-slot-variants.rs | 70 + src/test/ui/over-constrained-vregs.rs | 12 + .../overlap-doesnt-conflict-with-specialization.rs | 19 + ...verlap-permitted-for-annotated-marker-traits.rs | 26 + .../auxiliary/overloaded_autoderef_xc.rs | 30 + .../ui/overloaded/overloaded-autoderef-count.rs | 74 + .../ui/overloaded/overloaded-autoderef-indexing.rs | 20 + .../ui/overloaded/overloaded-autoderef-order.rs | 71 + .../ui/overloaded/overloaded-autoderef-vtable.rs | 39 + .../ui/overloaded/overloaded-autoderef-xcrate.rs | 9 + src/test/ui/overloaded/overloaded-autoderef.rs | 45 + .../overloaded/overloaded-calls-object-one-arg.rs | 13 + .../overloaded/overloaded-calls-object-two-args.rs | 13 + .../overloaded-calls-object-zero-args.rs | 13 + .../overloaded/overloaded-calls-param-vtables.rs | 32 + src/test/ui/overloaded/overloaded-calls-simple.rs | 78 + .../ui/overloaded/overloaded-calls-zero-args.rs | 30 + src/test/ui/overloaded/overloaded-deref-count.rs | 78 + src/test/ui/overloaded/overloaded-deref.rs | 43 + .../ui/overloaded/overloaded-index-assoc-list.rs | 48 + .../ui/overloaded/overloaded-index-autoderef.rs | 77 + .../ui/overloaded/overloaded-index-in-field.rs | 46 + src/test/ui/overloaded/overloaded-index.rs | 64 + .../overloaded_deref_with_ref_pattern.rs | 95 + ...overloaded_deref_with_ref_pattern_issue15609.rs | 37 + src/test/ui/owned-implies-static.rs | 8 + src/test/ui/packed/auxiliary/packed.rs | 19 + src/test/ui/packed/packed-struct-borrow-element.rs | 35 + src/test/ui/packed/packed-struct-drop-aligned.rs | 33 + src/test/ui/packed/packed-struct-generic-layout.rs | 32 + src/test/ui/packed/packed-struct-generic-size.rs | 44 + src/test/ui/packed/packed-struct-layout.rs | 28 + src/test/ui/packed/packed-struct-match.rs | 45 + src/test/ui/packed/packed-struct-optimized-enum.rs | 36 + src/test/ui/packed/packed-struct-size-xc.rs | 20 + src/test/ui/packed/packed-struct-size.rs | 157 + src/test/ui/packed/packed-struct-vec.rs | 120 + src/test/ui/packed/packed-tuple-struct-layout.rs | 21 + src/test/ui/packed/packed-tuple-struct-size.rs | 79 + .../packed-with-inference-vars-issue-61402.rs | 22 + .../abort-link-to-unwinding-crates.rs | 41 + src/test/ui/panic-runtime/abort.rs | 44 + .../auxiliary/exit-success-if-unwind.rs | 16 + src/test/ui/panic-runtime/link-to-abort.rs | 11 + src/test/ui/panic-runtime/link-to-unwind.rs | 10 + src/test/ui/panic-runtime/lto-abort.rs | 34 + src/test/ui/panic-runtime/lto-unwind.rs | 37 + src/test/ui/panic-uninitialized-zeroed.rs | 102 + src/test/ui/panics/panic-handler-chain.rs | 29 + src/test/ui/panics/panic-handler-flail-wildly.rs | 55 + src/test/ui/panics/panic-handler-set-twice.rs | 24 + src/test/ui/panics/panic-in-dtor-drops-fields.rs | 37 + src/test/ui/panics/panic-recover-propagate.rs | 26 + src/test/ui/panics/panic-safe.rs | 51 + src/test/ui/paren-free.rs | 7 + src/test/ui/parse-assoc-type-lt.rs | 9 + src/test/ui/parse-panic.rs | 8 + src/test/ui/parser-unicode-whitespace.rs | 12 + src/test/ui/path.rs | 8 + src/test/ui/paths-containing-nul.rs | 50 + src/test/ui/print-stdout-eprint-stderr.rs | 33 + src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs | 9 + src/test/ui/privacy/auxiliary/privacy_reexport.rs | 6 + .../ui/privacy/auxiliary/pub_use_mods_xcrate.rs | 10 + src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs | 3 + src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs | 3 + src/test/ui/privacy/priv-impl-prim-ty.rs | 11 + src/test/ui/privacy/privacy-ns.rs | 114 + src/test/ui/privacy/privacy-reexport.rs | 13 + src/test/ui/privacy/private-class-field.rs | 26 + src/test/ui/privacy/pub-extern-privacy.rs | 18 + src/test/ui/privacy/pub-use-xcrate.rs | 15 + src/test/ui/privacy/pub_use_mods_xcrate_exe.rs | 11 + src/test/ui/proc-macro/add-impl.rs | 14 + src/test/ui/proc-macro/append-impl.rs | 22 + src/test/ui/proc-macro/attr-args.rs | 13 + src/test/ui/proc-macro/attr-cfg.rs | 27 + src/test/ui/proc-macro/attr-on-trait.rs | 19 + src/test/ui/proc-macro/auxiliary/add-impl.rs | 21 + src/test/ui/proc-macro/auxiliary/append-impl.rs | 16 + src/test/ui/proc-macro/auxiliary/attr-args.rs | 28 + src/test/ui/proc-macro/auxiliary/attr-cfg.rs | 23 + src/test/ui/proc-macro/auxiliary/attr-on-trait.rs | 15 + src/test/ui/proc-macro/auxiliary/bang-macro.rs | 17 + src/test/ui/proc-macro/auxiliary/call-site.rs | 27 + .../ui/proc-macro/auxiliary/count_compound_ops.rs | 32 + .../auxiliary/custom-attr-only-one-derive.rs | 18 + src/test/ui/proc-macro/auxiliary/derive-a.rs | 15 + src/test/ui/proc-macro/auxiliary/derive-atob.rs | 15 + .../ui/proc-macro/auxiliary/derive-attr-cfg.rs | 14 + src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs | 17 + src/test/ui/proc-macro/auxiliary/derive-ctod.rs | 15 + src/test/ui/proc-macro/auxiliary/derive-nothing.rs | 13 + .../ui/proc-macro/auxiliary/derive-same-struct.rs | 21 + .../ui/proc-macro/auxiliary/derive-two-attrs.rs | 13 + src/test/ui/proc-macro/auxiliary/derive-union.rs | 18 + src/test/ui/proc-macro/auxiliary/double.rs | 15 + src/test/ui/proc-macro/auxiliary/empty-crate.rs | 5 + .../ui/proc-macro/auxiliary/expand-with-a-macro.rs | 22 + .../ui/proc-macro/auxiliary/external-crate-var.rs | 40 + .../ui/proc-macro/auxiliary/gen-lifetime-token.rs | 25 + .../ui/proc-macro/auxiliary/hygiene_example.rs | 7 + .../auxiliary/hygiene_example_codegen.rs | 27 + src/test/ui/proc-macro/auxiliary/issue-39889.rs | 17 + src/test/ui/proc-macro/auxiliary/issue-42708.rs | 18 + src/test/ui/proc-macro/auxiliary/issue-50061.rs | 12 + src/test/ui/proc-macro/auxiliary/modify-ast.rs | 47 + src/test/ui/proc-macro/auxiliary/negative-token.rs | 18 + src/test/ui/proc-macro/auxiliary/not-joint.rs | 30 + src/test/ui/proc-macro/auxiliary/span-api-tests.rs | 45 + .../ui/proc-macro/auxiliary/span-test-macros.rs | 9 + src/test/ui/proc-macro/bang-macro.rs | 11 + src/test/ui/proc-macro/call-site.rs | 16 + src/test/ui/proc-macro/count_compound_ops.rs | 11 + src/test/ui/proc-macro/crate-var.rs | 61 + .../ui/proc-macro/custom-attr-only-one-derive.rs | 16 + src/test/ui/proc-macro/derive-attr-cfg.rs | 17 + src/test/ui/proc-macro/derive-b.rs | 19 + src/test/ui/proc-macro/derive-same-struct.rs | 15 + src/test/ui/proc-macro/derive-same-struct.stdout | 1 + src/test/ui/proc-macro/derive-test.rs | 22 + src/test/ui/proc-macro/derive-two-attrs.rs | 15 + src/test/ui/proc-macro/derive-union.rs | 17 + src/test/ui/proc-macro/empty-crate.rs | 9 + src/test/ui/proc-macro/expand-with-a-macro.rs | 20 + src/test/ui/proc-macro/gen-lifetime-token.rs | 11 + src/test/ui/proc-macro/hygiene_example.rs | 20 + src/test/ui/proc-macro/issue-39889.rs | 12 + src/test/ui/proc-macro/issue-42708.rs | 26 + src/test/ui/proc-macro/issue-50061.rs | 23 + src/test/ui/proc-macro/load-two.rs | 23 + src/test/ui/proc-macro/modify-ast.rs | 26 + src/test/ui/proc-macro/negative-token.rs | 13 + src/test/ui/proc-macro/not-joint.rs | 24 + src/test/ui/proc-macro/smoke.rs | 20 + src/test/ui/proc-macro/span-api-tests.rs | 62 + src/test/ui/proc-macro/struct-field-macro.rs | 18 + src/test/ui/proc_macro.rs | 39 + src/test/ui/process/process-envs.rs | 53 + src/test/ui/process/process-exit.rs | 27 + src/test/ui/process/process-remove-from-env.rs | 47 + src/test/ui/process/process-sigpipe.rs | 36 + src/test/ui/process/process-spawn-nonexistent.rs | 15 + .../process/process-spawn-with-unicode-params.rs | 77 + .../ui/process/process-status-inherits-stdin.rs | 36 + src/test/ui/project-cache-issue-31849.rs | 65 + src/test/ui/project-cache-issue-37154.rs | 21 + src/test/ui/project-defer-unification.rs | 104 + src/test/ui/pure-sum.rs | 53 + src/test/ui/purity-infer.rs | 6 + src/test/ui/range-type-infer.rs | 22 + src/test/ui/range.rs | 51 + src/test/ui/range_inclusive.rs | 122 + src/test/ui/range_inclusive_gate.rs | 14 + src/test/ui/ranges-precedence.rs | 52 + src/test/ui/raw-fat-ptr.rs | 118 + src/test/ui/raw-str.rs | Bin 0 -> 847 bytes src/test/ui/rcvr-borrowed-to-region.rs | 29 + src/test/ui/reachable-unnameable-items.rs | 31 + src/test/ui/reachable-unnameable-type-alias.rs | 16 + src/test/ui/readalias.rs | 12 + src/test/ui/realloc-16687.rs | 183 + src/test/ui/reexport-should-still-link.rs | 10 + src/test/ui/reexport-star.rs | 16 + src/test/ui/reexport-test-harness-main.rs | 11 + src/test/ui/refer-to-other-statics-by-value.rs | 8 + .../regions-addr-of-interior-of-unique-box.rs | 23 + src/test/ui/regions/regions-addr-of-ret.rs | 9 + .../ui/regions/regions-assoc-type-region-bound.rs | 22 + .../ui/regions/regions-assoc-type-static-bound.rs | 19 + src/test/ui/regions/regions-borrow-at.rs | 13 + src/test/ui/regions/regions-borrow-evec-fixed.rs | 10 + src/test/ui/regions/regions-borrow-evec-uniq.rs | 16 + src/test/ui/regions/regions-borrow-uniq.rs | 12 + src/test/ui/regions/regions-bot.rs | 11 + .../regions/regions-bound-lists-feature-gate-2.rs | 14 + .../ui/regions/regions-bound-lists-feature-gate.rs | 18 + ...gions-close-over-type-parameter-successfully.rs | 23 + src/test/ui/regions/regions-copy-closure.rs | 21 + src/test/ui/regions/regions-creating-enums2.rs | 17 + src/test/ui/regions/regions-creating-enums5.rs | 17 + src/test/ui/regions/regions-debruijn-of-object.rs | 22 + src/test/ui/regions/regions-dependent-addr-of.rs | 113 + src/test/ui/regions/regions-dependent-autofn.rs | 15 + src/test/ui/regions/regions-dependent-autoslice.rs | 14 + src/test/ui/regions/regions-dependent-let-ref.rs | 12 + .../regions-early-bound-lifetime-in-assoc-fn.rs | 35 + .../ui/regions/regions-early-bound-trait-param.rs | 134 + .../regions-early-bound-used-in-bound-method.rs | 30 + .../regions/regions-early-bound-used-in-bound.rs | 28 + .../regions-early-bound-used-in-type-param.rs | 28 + .../ui/regions/regions-escape-into-other-fn.rs | 10 + src/test/ui/regions/regions-expl-self.rs | 15 + src/test/ui/regions/regions-fn-subtyping-2.rs | 20 + src/test/ui/regions/regions-fn-subtyping.rs | 30 + ...-region-outlives-static-outlives-free-region.rs | 17 + .../regions/regions-infer-borrow-scope-addr-of.rs | 23 + .../ui/regions/regions-infer-borrow-scope-view.rs | 11 + .../regions-infer-borrow-scope-within-loop-ok.rs | 13 + src/test/ui/regions/regions-infer-borrow-scope.rs | 15 + src/test/ui/regions/regions-infer-call-2.rs | 15 + src/test/ui/regions/regions-infer-call.rs | 11 + .../regions-infer-contravariance-due-to-ret.rs | 22 + .../regions-infer-reborrow-ref-mut-recurse.rs | 18 + .../regions-infer-region-in-fn-but-not-type.rs | 19 + .../ui/regions/regions-infer-static-from-proc.rs | 18 + src/test/ui/regions/regions-issue-21422.rs | 18 + src/test/ui/regions/regions-issue-22246.rs | 29 + .../regions/regions-lifetime-nonfree-late-bound.rs | 35 + ...gions-lifetime-static-items-enclosing-scopes.rs | 20 + src/test/ui/regions/regions-link-fn-args.rs | 15 + src/test/ui/regions/regions-lub-ref-ref-rc.rs | 28 + src/test/ui/regions/regions-mock-codegen.rs | 56 + .../regions-no-bound-in-argument-cleanup.rs | 24 + .../regions-no-variance-from-fn-generics.rs | 44 + src/test/ui/regions/regions-nullary-variant.rs | 15 + src/test/ui/regions/regions-params.rs | 19 + .../regions/regions-reassign-let-bound-pointer.rs | 18 + .../regions-reassign-match-bound-pointer.rs | 21 + src/test/ui/regions/regions-refcell.rs | 45 + ...d-regions-on-closures-to-inference-variables.rs | 59 + .../regions/regions-return-interior-of-option.rs | 24 + src/test/ui/regions/regions-scope-chain-example.rs | 43 + src/test/ui/regions/regions-self-impls.rs | 20 + src/test/ui/regions/regions-self-in-enums.rs | 17 + src/test/ui/regions/regions-simple.rs | 7 + src/test/ui/regions/regions-static-closure.rs | 19 + src/test/ui/regions/regions-trait-object-1.rs | 35 + ...ons-variance-contravariant-use-contravariant.rs | 27 + .../regions-variance-covariant-use-covariant.rs | 23 + src/test/ui/repeat-expr-in-static.rs | 8 + src/test/ui/repr_c_int_align.rs | 46 + src/test/ui/resolve-issue-2428.rs | 8 + src/test/ui/resolve-pseudo-shadowing.rs | 11 + src/test/ui/resource-assign-is-not-copy.rs | 33 + src/test/ui/resource-destruct.rs | 31 + src/test/ui/result-opt-conversions.rs | 47 + src/test/ui/ret-bang.rs | 13 + src/test/ui/ret-none.rs | 13 + src/test/ui/return-nil.rs | 6 + src/test/ui/rfcs/rfc-1014-2.rs | 30 + src/test/ui/rfcs/rfc-1014.rs | 34 + src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs | 11 + .../termination-trait-for-box-dyn-error.rs | 6 + .../termination-trait-for-empty.rs | 2 + .../termination-trait-for-exitcode.rs | 8 + .../termination-trait-for-impl-termination.rs | 4 + .../termination-trait-for-result-box-error_ok.rs | 6 + .../termination-trait-for-result.rs | 6 + .../termination-trait-for-str.rs | 4 + .../ui/rfcs/rfc-2005-default-binding-mode/box.rs | 18 + .../rfcs/rfc-2005-default-binding-mode/constref.rs | 40 + .../ui/rfcs/rfc-2005-default-binding-mode/enum.rs | 45 + .../ui/rfcs/rfc-2005-default-binding-mode/for.rs | 20 + .../rfcs/rfc-2005-default-binding-mode/general.rs | 249 ++ .../ui/rfcs/rfc-2005-default-binding-mode/lit.rs | 34 + .../ui/rfcs/rfc-2005-default-binding-mode/range.rs | 9 + .../rfc-2005-default-binding-mode/ref-region.rs | 16 + .../rfc-2005-default-binding-mode/reset-mode.rs | 14 + .../ui/rfcs/rfc-2005-default-binding-mode/slice.rs | 26 + .../rfcs/rfc-2005-default-binding-mode/struct.rs | 22 + .../rfc-2005-default-binding-mode/tuple-struct.rs | 19 + .../ui/rfcs/rfc-2005-default-binding-mode/tuple.rs | 12 + src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs | 15 + src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs | 20 + src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs | 32 + .../ui/rfcs/rfc-2151-raw-identifiers/macros.rs | 38 + src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs | 33 + src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs | 127 + ...-2421-unreserve-pure-offsetof-sizeof-alignof.rs | 15 + .../rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs | 23 + src/test/ui/rfcs/rfc1445/eq-allows-match.rs | 17 + src/test/ui/rfcs/rfc1623.rs | 75 + src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs | 5 + src/test/ui/rfcs/rfc1717/library-override.rs | 14 + src/test/ui/rfcs/rfc1857-drop-order.rs | 224 ++ src/test/ui/running-with-no-runtime.rs | 51 + src/test/ui/rustc-rust-log.rs | 14 + src/test/ui/rvalue-static-promotion.rs | 19 + src/test/ui/segfault-no-out-of-stack.rs | 50 + src/test/ui/semistatement-in-lambda.rs | 12 + .../ui/sepcomp/auxiliary/sepcomp-extern-lib.rs | 4 + src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs | 6 + src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs | 21 + src/test/ui/sepcomp/sepcomp-cci.rs | 33 + src/test/ui/sepcomp/sepcomp-extern.rs | 33 + src/test/ui/sepcomp/sepcomp-fns-backwards.rs | 33 + src/test/ui/sepcomp/sepcomp-fns.rs | 30 + src/test/ui/sepcomp/sepcomp-lib-lto.rs | 18 + src/test/ui/sepcomp/sepcomp-lib.rs | 16 + src/test/ui/sepcomp/sepcomp-statics.rs | 31 + src/test/ui/sepcomp/sepcomp-unwind.rs | 34 + src/test/ui/seq-compare.rs | 16 + src/test/ui/shadow.rs | 24 + src/test/ui/shadowed-use-visibility.rs | 13 + src/test/ui/shebang.rs | 5 + src/test/ui/signal-alternate-stack-cleanup.rs | 37 + src/test/ui/signal-exit-status.rs | 19 + src/test/ui/sigpipe-should-be-ignored.rs | 34 + src/test/ui/simd/simd-generics.rs | 39 + src/test/ui/simd/simd-intrinsic-float-math.rs | 103 + src/test/ui/simd/simd-intrinsic-float-minmax.rs | 54 + ...simd-intrinsic-generic-arithmetic-saturating.rs | 92 + .../ui/simd/simd-intrinsic-generic-arithmetic.rs | 120 + src/test/ui/simd/simd-intrinsic-generic-bitmask.rs | 61 + src/test/ui/simd/simd-intrinsic-generic-cast.rs | 121 + .../ui/simd/simd-intrinsic-generic-comparison.rs | 106 + .../ui/simd/simd-intrinsic-generic-elements.rs | 125 + src/test/ui/simd/simd-intrinsic-generic-gather.rs | 141 + .../ui/simd/simd-intrinsic-generic-reduction.rs | 165 + src/test/ui/simd/simd-intrinsic-generic-select.rs | 173 + src/test/ui/simd/simd-size-align.rs | 96 + src/test/ui/simd/simd-target-feature-mixup.rs | 185 + src/test/ui/simd/simd-type.rs | 16 + src/test/ui/simple-infer.rs | 6 + src/test/ui/simple_global_asm.rs | 24 + src/test/ui/size-and-align.rs | 20 + src/test/ui/sized-borrowed-pointer.rs | 10 + src/test/ui/sized-owned-pointer.rs | 11 + src/test/ui/sleep.rs | 19 + src/test/ui/slowparse-bstring.rs | 6 + src/test/ui/slowparse-string.rs | 6 + src/test/ui/specialization/assoc-ty-graph-cycle.rs | 25 + .../auxiliary/cross_crates_defaults.rs | 38 + src/test/ui/specialization/auxiliary/go_trait.rs | 43 + .../auxiliary/specialization_cross_crate.rs | 72 + src/test/ui/specialization/cross-crate-defaults.rs | 41 + .../defaultimpl/allowed-cross-crate.rs | 26 + .../defaultimpl/auxiliary/go_trait.rs | 43 + .../ui/specialization/defaultimpl/out-of-order.rs | 19 + .../defaultimpl/overlap-projection.rs | 25 + .../ui/specialization/defaultimpl/projection.rs | 42 + src/test/ui/specialization/issue-50452.rs | 19 + .../specialization-allowed-cross-crate.rs | 26 + .../ui/specialization/specialization-assoc-fns.rs | 29 + .../ui/specialization/specialization-basics.rs | 98 + .../specialization-cross-crate-no-gate.rs | 21 + .../specialization/specialization-cross-crate.rs | 50 + .../specialization-default-methods.rs | 86 + .../specialization/specialization-on-projection.rs | 24 + .../specialization/specialization-out-of-order.rs | 19 + .../specialization-overlap-projection.rs | 25 + .../specialization-projection-alias.rs | 26 + .../ui/specialization/specialization-projection.rs | 42 + .../specialization/specialization-super-traits.rs | 17 + ...ization-translate-projections-with-lifetimes.rs | 33 + ...ialization-translate-projections-with-params.rs | 32 + .../specialization-translate-projections.rs | 33 + src/test/ui/sse2.rs | 26 + src/test/ui/stable-addr-of.rs | 8 + src/test/ui/stack-probes-lto.rs | 19 + src/test/ui/stack-probes.rs | 68 + .../auxiliary/static-function-pointer-aux.rs | 4 + .../ui/statics/auxiliary/static-methods-crate.rs | 29 + .../statics/auxiliary/static_fn_inline_xc_aux.rs | 12 + .../ui/statics/auxiliary/static_fn_trait_xc_aux.rs | 11 + src/test/ui/statics/auxiliary/static_mut_xc.rs | 1 + src/test/ui/statics/static-fn-inline-xc.rs | 12 + src/test/ui/statics/static-fn-trait-xc.rs | 12 + src/test/ui/statics/static-function-pointer-xc.rs | 17 + src/test/ui/statics/static-function-pointer.rs | 16 + src/test/ui/statics/static-impl.rs | 66 + .../static-method-in-trait-with-tps-intracrate.rs | 28 + src/test/ui/statics/static-method-xcrate.rs | 13 + src/test/ui/statics/static-methods-in-traits.rs | 26 + src/test/ui/statics/static-methods-in-traits2.rs | 22 + src/test/ui/statics/static-mut-foreign.rs | 41 + src/test/ui/statics/static-mut-xc.rs | 39 + src/test/ui/statics/static-recursive.rs | 36 + src/test/ui/stdio-is-blocking.rs | 85 + src/test/ui/str-concat.rs | 9 + src/test/ui/str-multiline.rs | 13 + src/test/ui/string-box-error.rs | 12 + src/test/ui/string-escapes.rs | 7 + src/test/ui/struct-ctor-mangling.rs | 14 + src/test/ui/structs-enums/align-enum.rs | 54 + src/test/ui/structs-enums/align-struct.rs | 245 ++ src/test/ui/structs-enums/auxiliary/cci_class.rs | 14 + src/test/ui/structs-enums/auxiliary/cci_class_2.rs | 19 + src/test/ui/structs-enums/auxiliary/cci_class_3.rs | 19 + src/test/ui/structs-enums/auxiliary/cci_class_4.rs | 41 + src/test/ui/structs-enums/auxiliary/cci_class_6.rs | 25 + .../ui/structs-enums/auxiliary/cci_class_cast.rs | 50 + .../ui/structs-enums/auxiliary/cci_class_trait.rs | 5 + .../ui/structs-enums/auxiliary/empty-struct.rs | 9 + .../auxiliary/namespaced_enum_emulate_flat.rs | 25 + .../ui/structs-enums/auxiliary/namespaced_enums.rs | 10 + .../structs-enums/auxiliary/newtype_struct_xc.rs | 3 + .../auxiliary/struct_destructuring_cross_crate.rs | 6 + .../auxiliary/struct_variant_xc_aux.rs | 8 + .../auxiliary/xcrate_struct_aliases.rs | 6 + src/test/ui/structs-enums/borrow-tuple-fields.rs | 38 + .../class-cast-to-trait-cross-crate-2.rs | 20 + .../class-cast-to-trait-multiple-types.rs | 93 + src/test/ui/structs-enums/class-cast-to-trait.rs | 60 + src/test/ui/structs-enums/class-dtor.rs | 25 + src/test/ui/structs-enums/class-exports.rs | 31 + .../class-impl-very-parameterized-trait.rs | 107 + .../class-implement-trait-cross-crate.rs | 59 + .../ui/structs-enums/class-implement-traits.rs | 63 + .../ui/structs-enums/class-method-cross-crate.rs | 13 + .../ui/structs-enums/class-methods-cross-crate.rs | 14 + src/test/ui/structs-enums/class-methods.rs | 30 + .../class-poly-methods-cross-crate.rs | 16 + src/test/ui/structs-enums/class-poly-methods.rs | 37 + src/test/ui/structs-enums/class-separate-impl.rs | 65 + src/test/ui/structs-enums/class-str-field.rs | 21 + src/test/ui/structs-enums/class-typarams.rs | 32 + src/test/ui/structs-enums/classes-cross-crate.rs | 13 + .../ui/structs-enums/classes-self-referential.rs | 20 + .../ui/structs-enums/classes-simple-cross-crate.rs | 12 + src/test/ui/structs-enums/classes-simple-method.rs | 28 + src/test/ui/structs-enums/classes-simple.rs | 23 + src/test/ui/structs-enums/classes.rs | 51 + .../ui/structs-enums/codegen-tag-static-padding.rs | 59 + src/test/ui/structs-enums/compare-generic-enums.rs | 16 + .../ui/structs-enums/discrim-explicit-23030.rs | 147 + src/test/ui/structs-enums/empty-struct-braces.rs | 213 ++ src/test/ui/structs-enums/empty-tag.rs | 21 + src/test/ui/structs-enums/enum-alignment.rs | 24 + src/test/ui/structs-enums/enum-clike-ffi-as-int.rs | 33 + src/test/ui/structs-enums/enum-discr.rs | 23 + .../ui/structs-enums/enum-discrim-autosizing.rs | 53 + .../ui/structs-enums/enum-discrim-manual-sizing.rs | 111 + .../structs-enums/enum-discrim-range-overflow.rs | 26 + .../ui/structs-enums/enum-discrim-width-stuff.rs | 44 + src/test/ui/structs-enums/enum-disr-val-pretty.rs | 17 + .../ui/structs-enums/enum-export-inheritance.rs | 15 + .../ui/structs-enums/enum-layout-optimization.rs | 50 + .../enum-non-c-like-repr-c-and-int.rs | 171 + .../ui/structs-enums/enum-non-c-like-repr-c.rs | 171 + .../ui/structs-enums/enum-non-c-like-repr-int.rs | 167 + src/test/ui/structs-enums/enum-null-pointer-opt.rs | 74 + .../enum-nullable-const-null-with-fields.rs | 13 + .../enum-nullable-simplifycfg-misopt.rs | 17 + src/test/ui/structs-enums/enum-univariant-repr.rs | 51 + src/test/ui/structs-enums/enum-variants.rs | 18 + src/test/ui/structs-enums/enum-vec-initializer.rs | 17 + src/test/ui/structs-enums/export-abstract-tag.rs | 15 + src/test/ui/structs-enums/export-tag-variant.rs | 9 + src/test/ui/structs-enums/expr-if-struct.rs | 32 + src/test/ui/structs-enums/expr-match-struct.rs | 31 + .../ui/structs-enums/field-destruction-order.rs | 47 + src/test/ui/structs-enums/foreign-struct.rs | 19 + src/test/ui/structs-enums/functional-struct-upd.rs | 12 + src/test/ui/structs-enums/ivec-tag.rs | 22 + .../module-qualified-struct-destructure.rs | 14 + .../namespaced-enum-emulate-flat-xc.rs | 25 + .../structs-enums/namespaced-enum-emulate-flat.rs | 44 + .../namespaced-enum-glob-import-xcrate.rs | 26 + .../structs-enums/namespaced-enum-glob-import.rs | 35 + .../ui/structs-enums/namespaced-enums-xcrate.rs | 16 + src/test/ui/structs-enums/namespaced-enums.rs | 17 + .../ui/structs-enums/nested-enum-same-names.rs | 27 + .../ui/structs-enums/newtype-struct-drop-run.rs | 21 + .../ui/structs-enums/newtype-struct-with-dtor.rs | 20 + src/test/ui/structs-enums/newtype-struct-xc-2.rs | 15 + src/test/ui/structs-enums/newtype-struct-xc.rs | 10 + src/test/ui/structs-enums/nonzero-enum.rs | 30 + src/test/ui/structs-enums/numeric-fields.rs | 12 + .../object-lifetime-default-from-ref-struct.rs | 58 + .../object-lifetime-default-from-rptr-struct.rs | 37 + src/test/ui/structs-enums/rec-align-u32.rs | 56 + src/test/ui/structs-enums/rec-align-u64.rs | 101 + src/test/ui/structs-enums/rec-auto.rs | 14 + src/test/ui/structs-enums/rec-extend.rs | 18 + src/test/ui/structs-enums/rec-tup.rs | 31 + src/test/ui/structs-enums/rec.rs | 24 + src/test/ui/structs-enums/record-pat.rs | 19 + src/test/ui/structs-enums/resource-in-struct.rs | 37 + src/test/ui/structs-enums/simple-generic-tag.rs | 11 + .../ui/structs-enums/simple-match-generic-tag.rs | 13 + src/test/ui/structs-enums/small-enum-range-edge.rs | 27 + .../ui/structs-enums/small-enums-with-fields.rs | 33 + src/test/ui/structs-enums/struct-aliases-xcrate.rs | 25 + src/test/ui/structs-enums/struct-aliases.rs | 64 + .../struct-destructuring-cross-crate.rs | 12 + .../ui/structs-enums/struct-field-shorthand.rs | 26 + .../structs-enums/struct-like-variant-construct.rs | 18 + .../ui/structs-enums/struct-like-variant-match.rs | 33 + .../struct-lit-functional-no-fields.rs | 26 + src/test/ui/structs-enums/struct-literal-dtor.rs | 18 + .../ui/structs-enums/struct-new-as-field-name.rs | 10 + .../ui/structs-enums/struct-order-of-eval-1.rs | 16 + .../ui/structs-enums/struct-order-of-eval-2.rs | 16 + .../ui/structs-enums/struct-order-of-eval-3.rs | 37 + .../ui/structs-enums/struct-order-of-eval-4.rs | 34 + src/test/ui/structs-enums/struct-partial-move-1.rs | 21 + src/test/ui/structs-enums/struct-partial-move-2.rs | 28 + .../structs-enums/struct-path-associated-type.rs | 27 + src/test/ui/structs-enums/struct-path-self.rs | 45 + .../ui/structs-enums/struct-pattern-matching.rs | 18 + src/test/ui/structs-enums/struct-return.rs | 64 + .../struct-variant-field-visibility.rs | 17 + src/test/ui/structs-enums/struct_variant_xc.rs | 11 + .../ui/structs-enums/struct_variant_xc_match.rs | 14 + src/test/ui/structs-enums/tag-align-dyn-u64.rs | 29 + .../ui/structs-enums/tag-align-dyn-variants.rs | 67 + src/test/ui/structs-enums/tag-align-shape.rs | 20 + src/test/ui/structs-enums/tag-align-u64.rs | 29 + src/test/ui/structs-enums/tag-disr-val-shape.rs | 20 + src/test/ui/structs-enums/tag-exports.rs | 21 + src/test/ui/structs-enums/tag-in-block.rs | 15 + .../tag-variant-disr-type-mismatch.rs | 12 + src/test/ui/structs-enums/tag-variant-disr-val.rs | 66 + src/test/ui/structs-enums/tag.rs | 30 + .../ui/structs-enums/tuple-struct-construct.rs | 8 + .../tuple-struct-constructor-pointer.rs | 12 + .../ui/structs-enums/tuple-struct-destructuring.rs | 10 + src/test/ui/structs-enums/tuple-struct-matching.rs | 13 + src/test/ui/structs-enums/tuple-struct-trivial.rs | 8 + src/test/ui/structs-enums/uninstantiable-struct.rs | 4 + .../ui/structs-enums/unit-like-struct-drop-run.rs | 23 + src/test/ui/structs-enums/unit-like-struct.rs | 9 + .../ui/structs-enums/variant-structs-trivial.rs | 10 + src/test/ui/structured-compare.rs | 30 + src/test/ui/super-fast-paren-parsing.rs | 24 + src/test/ui/super.rs | 16 + src/test/ui/supported-cast.rs | 206 ++ src/test/ui/svh-add-nothing.rs | 14 + src/test/ui/swap-1.rs | 10 + src/test/ui/swap-2.rs | 14 + src/test/ui/swap-overlapping.rs | 44 + src/test/ui/tail-call-arg-leak.rs | 9 + src/test/ui/tail-cps.rs | 17 + src/test/ui/tail-direct.rs | 7 + src/test/ui/tcp-stress.rs | 66 + src/test/ui/terminate-in-initializer.rs | 33 + .../ui/test-allow-dead-extern-static-no-warning.rs | 11 + src/test/ui/test-allow-fail-attr.rs | 16 + ...nature-verification-for-explicit-return-type.rs | 12 + src/test/ui/test-main-not-dead-attr.rs | 9 + src/test/ui/test-main-not-dead.rs | 6 + src/test/ui/test-runner-hides-buried-main.rs | 15 + src/test/ui/test-runner-hides-main.rs | 5 + src/test/ui/test-runner-hides-start.rs | 7 + src/test/ui/test-should-fail-good-message.rs | 14 + src/test/ui/test-vs-cfg-test.rs | 9 + src/test/ui/thin-lto-global-allocator.rs | 7 + src/test/ui/thinlto/all-crates.rs | 8 + src/test/ui/thinlto/auxiliary/dylib.rs | 6 + src/test/ui/thinlto/auxiliary/msvc-imp-present.rs | 11 + .../ui/thinlto/auxiliary/thin-lto-inlines-aux.rs | 7 + src/test/ui/thinlto/dylib-works.rs | 9 + src/test/ui/thinlto/msvc-imp-present.rs | 22 + src/test/ui/thinlto/thin-lto-inlines.rs | 30 + src/test/ui/thinlto/thin-lto-inlines2.rs | 28 + src/test/ui/thinlto/weak-works.rs | 28 + src/test/ui/thread-local-not-in-prelude.rs | 10 + .../auxiliary/thread-local-extern-static.rs | 10 + src/test/ui/threads-sendsync/comm.rs | 22 + .../threads-sendsync/send-is-not-static-par-for.rs | 34 + src/test/ui/threads-sendsync/send-resource.rs | 39 + .../ui/threads-sendsync/send-type-inference.rs | 19 + src/test/ui/threads-sendsync/send_str_hashmap.rs | 53 + src/test/ui/threads-sendsync/send_str_treemap.rs | 58 + src/test/ui/threads-sendsync/sendable-class.rs | 28 + src/test/ui/threads-sendsync/sendfn-is-a-block.rs | 11 + .../threads-sendsync/sendfn-spawn-with-fn-arg.rs | 23 + src/test/ui/threads-sendsync/spawn-fn.rs | 25 + src/test/ui/threads-sendsync/spawn-types.rs | 25 + src/test/ui/threads-sendsync/spawn.rs | 10 + src/test/ui/threads-sendsync/spawn2.rs | 31 + .../ui/threads-sendsync/spawning-with-debug.rs | 15 + .../threads-sendsync/std-sync-right-kind-impls.rs | 16 + src/test/ui/threads-sendsync/sync-send-atomics.rs | 14 + src/test/ui/threads-sendsync/sync-send-in-std.rs | 25 + .../sync-send-iterators-in-libcollections.rs | 71 + .../sync-send-iterators-in-libcore.rs | 104 + src/test/ui/threads-sendsync/task-comm-0.rs | 30 + src/test/ui/threads-sendsync/task-comm-1.rs | 14 + src/test/ui/threads-sendsync/task-comm-10.rs | 33 + src/test/ui/threads-sendsync/task-comm-11.rs | 21 + src/test/ui/threads-sendsync/task-comm-12.rs | 29 + src/test/ui/threads-sendsync/task-comm-13.rs | 18 + src/test/ui/threads-sendsync/task-comm-14.rs | 36 + src/test/ui/threads-sendsync/task-comm-15.rs | 28 + src/test/ui/threads-sendsync/task-comm-16.rs | 111 + src/test/ui/threads-sendsync/task-comm-17.rs | 17 + src/test/ui/threads-sendsync/task-comm-3.rs | 63 + src/test/ui/threads-sendsync/task-comm-4.rs | 45 + src/test/ui/threads-sendsync/task-comm-5.rs | 17 + src/test/ui/threads-sendsync/task-comm-6.rs | 42 + src/test/ui/threads-sendsync/task-comm-7.rs | 59 + src/test/ui/threads-sendsync/task-comm-9.rs | 35 + src/test/ui/threads-sendsync/task-comm-chan-nil.rs | 13 + src/test/ui/threads-sendsync/task-life-0.rs | 14 + .../threads-sendsync/task-spawn-move-and-copy.rs | 25 + src/test/ui/threads-sendsync/task-stderr.rs | 32 + .../threads-sendsync/thread-local-extern-static.rs | 27 + .../ui/threads-sendsync/thread-local-syntax.rs | 22 + src/test/ui/threads-sendsync/threads.rs | 16 + .../tls-dtors-are-run-in-a-static-binary.rs | 22 + src/test/ui/threads-sendsync/tls-init-on-init.rs | 44 + src/test/ui/threads-sendsync/tls-try-with.rs | 30 + src/test/ui/tool_attributes.rs | 13 + src/test/ui/tool_lints_2018_preview.rs | 7 + src/test/ui/trailing-comma.rs | 37 + src/test/ui/traits/anon-trait-static-method.rs | 15 + src/test/ui/traits/anon_trait_static_method_exe.rs | 12 + src/test/ui/traits/assignability-trait.rs | 47 + .../traits/astconv-cycle-between-trait-and-type.rs | 29 + src/test/ui/traits/augmented-assignments-trait.rs | 12 + src/test/ui/traits/auto-traits.rs | 31 + .../auxiliary/anon_trait_static_method_lib.rs | 9 + src/test/ui/traits/auxiliary/go_trait.rs | 43 + src/test/ui/traits/auxiliary/trait_alias.rs | 13 + .../auxiliary/trait_default_method_xc_aux.rs | 40 + .../auxiliary/trait_default_method_xc_aux_2.rs | 17 + .../auxiliary/trait_inheritance_auto_xc_2_aux.rs | 9 + .../auxiliary/trait_inheritance_auto_xc_aux.rs | 7 + .../auxiliary/trait_inheritance_overloading_xc.rs | 38 + src/test/ui/traits/auxiliary/trait_xc_call_aux.rs | 11 + src/test/ui/traits/auxiliary/traitimpl.rs | 7 + src/test/ui/traits/cycle-trait-type-trait.rs | 25 + .../ui/traits/default-method-supertrait-vtable.rs | 28 + src/test/ui/traits/dyn-trait.rs | 17 + src/test/ui/traits/fmt-pointer-trait.rs | 24 + src/test/ui/traits/impl-implicit-trait.rs | 26 + .../ui/traits/impl-inherent-prefer-over-trait.rs | 30 + .../traits/infer-from-object-trait-issue-26952.rs | 26 + src/test/ui/traits/inherent-trait-method-order.rs | 25 + .../ui/traits/kindck-owned-trait-contains-1.rs | 23 + src/test/ui/traits/multiple-trait-bounds.rs | 9 + src/test/ui/traits/object-one-type-two-traits.rs | 33 + .../overlap-permitted-for-marker-traits-neg.rs | 12 + .../traits/overlap-permitted-for-marker-traits.rs | 27 + .../ui/traits/parameterized-trait-with-bounds.rs | 21 + src/test/ui/traits/principal-less-trait-objects.rs | 42 + src/test/ui/traits/supertrait-default-generics.rs | 39 + src/test/ui/traits/syntax-trait-polarity.rs | 21 + .../ui/traits/trait-alias-import-cross-crate.rs | 14 + src/test/ui/traits/trait-alias-import.rs | 40 + src/test/ui/traits/trait-bounds-basic.rs | 25 + .../trait-bounds-impl-comparison-duplicates.rs | 16 + src/test/ui/traits/trait-bounds-in-arc.rs | 109 + src/test/ui/traits/trait-bounds-recursion.rs | 20 + src/test/ui/traits/trait-bounds.rs | 30 + src/test/ui/traits/trait-cache-issue-18209.rs | 20 + src/test/ui/traits/trait-coercion-generic.rs | 25 + src/test/ui/traits/trait-coercion.rs | 36 + src/test/ui/traits/trait-composition-trivial.rs | 12 + src/test/ui/traits/trait-copy-guessing.rs | 38 + .../ui/traits/trait-default-method-bound-subst.rs | 18 + .../ui/traits/trait-default-method-bound-subst2.rs | 16 + .../ui/traits/trait-default-method-bound-subst3.rs | 17 + .../ui/traits/trait-default-method-bound-subst4.rs | 19 + src/test/ui/traits/trait-default-method-bound.rs | 16 + src/test/ui/traits/trait-default-method-xc-2.rs | 26 + src/test/ui/traits/trait-default-method-xc.rs | 81 + ...t-false-ambiguity-where-clause-builtin-bound.rs | 16 + src/test/ui/traits/trait-generic.rs | 45 + src/test/ui/traits/trait-impl-2.rs | 19 + src/test/ui/traits/trait-impl.rs | 41 + src/test/ui/traits/trait-inheritance-auto-xc-2.rs | 23 + src/test/ui/traits/trait-inheritance-auto-xc.rs | 25 + src/test/ui/traits/trait-inheritance-auto.rs | 29 + .../trait-inheritance-call-bound-inherited.rs | 20 + .../trait-inheritance-call-bound-inherited2.rs | 23 + ...-inheritance-cast-without-call-to-supertrait.rs | 33 + src/test/ui/traits/trait-inheritance-cast.rs | 33 + .../trait-inheritance-cross-trait-call-xc.rs | 20 + .../traits/trait-inheritance-cross-trait-call.rs | 19 + src/test/ui/traits/trait-inheritance-diamond.rs | 28 + .../trait-inheritance-multiple-inheritors.rs | 23 + .../ui/traits/trait-inheritance-multiple-params.rs | 26 + src/test/ui/traits/trait-inheritance-num.rs | 13 + src/test/ui/traits/trait-inheritance-num0.rs | 24 + src/test/ui/traits/trait-inheritance-num1.rs | 15 + src/test/ui/traits/trait-inheritance-num2.rs | 86 + src/test/ui/traits/trait-inheritance-num3.rs | 19 + src/test/ui/traits/trait-inheritance-num5.rs | 26 + .../traits/trait-inheritance-overloading-simple.rs | 27 + .../traits/trait-inheritance-overloading-xc-exe.rs | 20 + .../ui/traits/trait-inheritance-overloading.rs | 47 + .../traits/trait-inheritance-self-in-supertype.rs | 62 + src/test/ui/traits/trait-inheritance-self.rs | 29 + src/test/ui/traits/trait-inheritance-simple.rs | 24 + src/test/ui/traits/trait-inheritance-static.rs | 26 + src/test/ui/traits/trait-inheritance-static2.rs | 29 + src/test/ui/traits/trait-inheritance-subst.rs | 27 + src/test/ui/traits/trait-inheritance-subst2.rs | 37 + src/test/ui/traits/trait-inheritance-visibility.rs | 20 + src/test/ui/traits/trait-inheritance2.rs | 26 + src/test/ui/traits/trait-item-inside-macro.rs | 30 + src/test/ui/traits/trait-object-auto-dedup.rs | 46 + src/test/ui/traits/trait-object-exclusion.rs | 19 + src/test/ui/traits/trait-object-generics.rs | 43 + src/test/ui/traits/trait-object-lifetime-first.rs | 13 + .../ui/traits/trait-object-with-lifetime-bound.rs | 34 + src/test/ui/traits/trait-region-pointer-simple.rs | 21 + src/test/ui/traits/trait-safety-ok-cc.rs | 24 + src/test/ui/traits/trait-safety-ok.rs | 18 + .../ui/traits/trait-static-method-overwriting.rs | 34 + src/test/ui/traits/trait-to-str.rs | 36 + src/test/ui/traits/trait-where-clause-vs-impl.rs | 45 + src/test/ui/traits/trait-with-bounds-default.rs | 32 + .../ui/traits/traits-assoc-type-in-supertrait.rs | 23 + src/test/ui/traits/traits-conditional-dispatch.rs | 35 + src/test/ui/traits/traits-conditional-model-fn.rs | 60 + src/test/ui/traits/traits-default-method-macro.rs | 20 + src/test/ui/traits/traits-default-method-mut.rs | 11 + src/test/ui/traits/traits-default-method-self.rs | 18 + .../ui/traits/traits-default-method-trivial.rs | 21 + src/test/ui/traits/traits-elaborate-type-region.rs | 49 + .../traits-impl-object-overlap-issue-23853.rs | 18 + src/test/ui/traits/traits-issue-22019.rs | 34 + src/test/ui/traits/traits-issue-22110.rs | 27 + src/test/ui/traits/traits-issue-22655.rs | 23 + src/test/ui/traits/traits-issue-23003.rs | 32 + src/test/ui/traits/traits-issue-26339.rs | 31 + .../traits-multidispatch-infer-convert-target.rs | 36 + src/test/ui/traits/traits-repeated-supertrait.rs | 48 + src/test/ui/traits/ufcs-trait-object.rs | 17 + src/test/ui/traits/use-trait-before-def.rs | 10 + .../ui/transmute-non-immediate-to-immediate.rs | 11 + src/test/ui/transmute-specialization.rs | 15 + src/test/ui/trivial-message.rs | 16 + src/test/ui/try-block.rs | 75 + src/test/ui/try-from-int-error-partial-eq.rs | 12 + src/test/ui/try-is-identifier-edition2015.rs | 11 + src/test/ui/try-operator-custom.rs | 63 + src/test/ui/try-operator-hygiene.rs | 26 + src/test/ui/try-operator.rs | 193 ++ src/test/ui/try-wait.rs | 61 + src/test/ui/try_from.rs | 37 + src/test/ui/tup.rs | 21 + src/test/ui/tuple-index-fat-types.rs | 13 + src/test/ui/tuple-index.rs | 32 + src/test/ui/tydesc-name.rs | 14 + src/test/ui/type-ascription.rs | 39 + src/test/ui/type-id-higher-rank-2.rs | 31 + src/test/ui/type-id-higher-rank.rs | 72 + src/test/ui/type-in-nested-module.rs | 17 + src/test/ui/type-infer-generalize-ty-var.rs | 56 + src/test/ui/type-namespace.rs | 7 + src/test/ui/type-param-constraints.rs | 39 + src/test/ui/type-param.rs | 11 + src/test/ui/type-params-in-for-each.rs | 23 + src/test/ui/type-ptr.rs | 10 + src/test/ui/type-sizes.rs | 116 + src/test/ui/type-use-i1-versus-i8.rs | 12 + src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs | 9 + src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs | 12 + src/test/ui/typeck_type_placeholder_1.rs | 32 + src/test/ui/typeclasses-eq-example-static.rs | 69 + src/test/ui/typeclasses-eq-example.rs | 65 + src/test/ui/typeid-intrinsic.rs | 87 + src/test/ui/typestate-cfg-nesting.rs | 20 + src/test/ui/typestate-multi-decl.rs | 7 + src/test/ui/ufcs-polymorphic-paths.rs | 154 + src/test/ui/ufcs-type-params.rs | 15 + src/test/ui/unary-minus-suffix-inference.rs | 23 + .../auxiliary/unboxed-closures-cross-crate.rs | 16 + .../unboxed-closures-all-traits.rs | 21 + .../unboxed-closures-blanket-fn-mut.rs | 27 + .../unboxed-closures-blanket-fn.rs | 27 + .../ui/unboxed-closures/unboxed-closures-boxed.rs | 16 + .../ui/unboxed-closures/unboxed-closures-by-ref.rs | 24 + .../unboxed-closures-call-fn-autoderef.rs | 18 + .../unboxed-closures-call-sugar-autoderef.rs | 15 + ...unboxed-closures-call-sugar-object-autoderef.rs | 15 + .../unboxed-closures-call-sugar-object.rs | 13 + .../unboxed-closures-counter-not-moved.rs | 28 + .../unboxed-closures-cross-crate.rs | 14 + .../unboxed-closures-direct-sugary-call.rs | 8 + .../ui/unboxed-closures/unboxed-closures-drop.rs | 117 + .../unboxed-closures-extern-fn-hr.rs | 31 + .../unboxed-closures/unboxed-closures-extern-fn.rs | 27 + .../unboxed-closures-fn-as-fnmut-and-fnonce.rs | 44 + .../unboxed-closures-fnmut-as-fnonce.rs | 33 + .../unboxed-closures/unboxed-closures-generic.rs | 13 + ...closures-infer-arg-types-from-expected-bound.rs | 23 + ...es-infer-arg-types-from-expected-object-type.rs | 19 + ...r-arg-types-w-bound-regs-from-expected-bound.rs | 23 + .../unboxed-closures-infer-explicit-call-early.rs | 8 + .../unboxed-closures-infer-fnmut-calling-fnmut.rs | 19 + .../unboxed-closures-infer-fnmut-move.rs | 16 + .../unboxed-closures-infer-fnmut.rs | 15 + .../unboxed-closures-infer-fnonce-move.rs | 25 + .../unboxed-closures-infer-fnonce.rs | 25 + .../unboxed-closures-infer-kind.rs | 27 + .../unboxed-closures-infer-recursive-fn.rs | 45 + .../unboxed-closures-infer-upvar.rs | 13 + .../unboxed-closures-manual-impl.rs | 31 + .../unboxed-closures-monomorphization.rs | 26 + ...ed-closures-move-from-projection-issue-30046.rs | 26 + .../unboxed-closures-move-mutable.rs | 30 + ...-closures-move-some-upvars-in-by-ref-closure.rs | 23 + .../unboxed-closures/unboxed-closures-prelude.rs | 18 + .../ui/unboxed-closures/unboxed-closures-simple.rs | 10 + .../unboxed-closures-single-word-env.rs | 22 + .../unboxed-closures-static-call-fn-once.rs | 7 + .../unboxed-closures-sugar-object.rs | 25 + .../unboxed-closures-unique-type-id.rs | 25 + .../unboxed-closures/unboxed-closures-zero-args.rs | 8 + src/test/ui/underscore-lifetimes.rs | 38 + src/test/ui/underscore-method-after-integer.rs | 11 + src/test/ui/uniform-paths/auxiliary/issue-53691.rs | 7 + src/test/ui/uniform-paths/basic-nested.rs | 61 + src/test/ui/uniform-paths/basic.rs | 33 + src/test/ui/uniform-paths/issue-53691.rs | 9 + src/test/ui/uniform-paths/macros-nested.rs | 53 + src/test/ui/uniform-paths/macros.rs | 36 + src/test/ui/uniform-paths/same-crate.rs | 98 + src/test/ui/unify-return-ty.rs | 16 + src/test/ui/uninit-empty-types.rs | 17 + src/test/ui/union/auxiliary/union.rs | 4 + src/test/ui/union/union-align.rs | 63 + src/test/ui/union/union-backcomp.rs | 25 + src/test/ui/union/union-basic.rs | 59 + src/test/ui/union/union-c-interop.rs | 37 + src/test/ui/union/union-const-codegen.rs | 17 + src/test/ui/union/union-const-eval-field.rs | 45 + src/test/ui/union/union-drop-assign.rs | 38 + src/test/ui/union/union-drop.rs | 60 + src/test/ui/union/union-inherent-method.rs | 14 + src/test/ui/union/union-macro.rs | 24 + src/test/ui/union/union-nodrop.rs | 59 + src/test/ui/union/union-nonzero.rs | 51 + src/test/ui/union/union-overwrite.rs | 73 + src/test/ui/union/union-packed.rs | 171 + src/test/ui/union/union-pat-refutability.rs | 54 + src/test/ui/union/union-trait-impl.rs | 17 + src/test/ui/union/union-transmute.rs | 28 + src/test/ui/unique/unique-assign-copy.rs | 13 + src/test/ui/unique/unique-assign-drop.rs | 12 + src/test/ui/unique/unique-assign-generic.rs | 12 + src/test/ui/unique/unique-assign.rs | 9 + src/test/ui/unique/unique-autoderef-field.rs | 11 + src/test/ui/unique/unique-autoderef-index.rs | 7 + src/test/ui/unique/unique-cmp.rs | 12 + src/test/ui/unique/unique-containing-tag.rs | 27 + src/test/ui/unique/unique-create.rs | 13 + src/test/ui/unique/unique-decl-init-copy.rs | 12 + src/test/ui/unique/unique-decl-init.rs | 8 + src/test/ui/unique/unique-decl-move.rs | 8 + src/test/ui/unique/unique-decl.rs | 11 + src/test/ui/unique/unique-deref.rs | 7 + src/test/ui/unique/unique-destructure.rs | 10 + src/test/ui/unique/unique-drop-complex.rs | 8 + src/test/ui/unique/unique-ffi-symbols.rs | 16 + src/test/ui/unique/unique-fn-arg-move.rs | 11 + src/test/ui/unique/unique-fn-arg-mut.rs | 12 + src/test/ui/unique/unique-fn-arg.rs | 12 + src/test/ui/unique/unique-fn-ret.rs | 10 + src/test/ui/unique/unique-generic-assign.rs | 11 + src/test/ui/unique/unique-in-tag.rs | 22 + src/test/ui/unique/unique-in-vec-copy.rs | 16 + src/test/ui/unique/unique-in-vec.rs | 7 + src/test/ui/unique/unique-init.rs | 8 + src/test/ui/unique/unique-kinds.rs | 65 + src/test/ui/unique/unique-log.rs | 7 + src/test/ui/unique/unique-match-discrim.rs | 12 + src/test/ui/unique/unique-move-drop.rs | 11 + src/test/ui/unique/unique-move-temp.rs | 9 + src/test/ui/unique/unique-move.rs | 10 + src/test/ui/unique/unique-mutable.rs | 8 + src/test/ui/unique/unique-object-move.rs | 20 + src/test/ui/unique/unique-pat-2.rs | 18 + src/test/ui/unique/unique-pat-3.rs | 17 + src/test/ui/unique/unique-pat.rs | 15 + src/test/ui/unique/unique-rec.rs | 10 + src/test/ui/unique/unique-send-2.rs | 35 + src/test/ui/unique/unique-send.rs | 11 + src/test/ui/unique/unique-swap.rs | 12 + src/test/ui/unit.rs | 17 + src/test/ui/unnamed_argument_mode.rs | 14 + src/test/ui/unreachable-code-1.rs | 19 + src/test/ui/unreachable-code.rs | 28 + src/test/ui/unsafe-coercion.rs | 17 + src/test/ui/unsafe-fn-called-from-unsafe-blk.rs | 18 + src/test/ui/unsafe-fn-called-from-unsafe-fn.rs | 17 + src/test/ui/unsafe-pointer-assignability.rs | 11 + src/test/ui/unsized-locals/autoderef.rs | 49 + src/test/ui/unsized-locals/box-fnonce.rs | 10 + .../by-value-trait-object-safety-withdefault.rs | 23 + .../ui/unsized-locals/reference-unsized-locals.rs | 9 + .../ui/unsized-locals/simple-unsized-locals.rs | 8 + src/test/ui/unsized-locals/unsized-parameters.rs | 12 + src/test/ui/unsized-tuple-impls.rs | 21 + src/test/ui/unsized.rs | 25 + src/test/ui/unsized2.rs | 97 + src/test/ui/unused-move-capture.rs | 10 + src/test/ui/unused-move.rs | 15 + src/test/ui/unwind-resource.rs | 39 + src/test/ui/unwind-unique.rs | 16 + src/test/ui/use-crate-name-alias.rs | 7 + src/test/ui/use-import-export.rs | 12 + src/test/ui/use-keyword-2.rs | 23 + src/test/ui/use-mod.rs | 33 + src/test/ui/use-nested-groups.rs | 32 + src/test/ui/use.rs | 23 + src/test/ui/use_inline_dtor.rs | 10 + src/test/ui/using-target-feature-unstable.rs | 11 + src/test/ui/utf8-bom.rs | 6 + src/test/ui/utf8.rs | 50 + src/test/ui/utf8_chars.rs | 31 + src/test/ui/variadic-ffi.rs | 84 + .../ui/variance-intersection-of-ref-and-opt-ref.rs | 25 + src/test/ui/variance-iterators-in-libcore.rs | 9 + src/test/ui/volatile-fat-ptr.rs | 15 + src/test/ui/wait-forked-but-failed-child.rs | 62 + src/test/ui/warn-ctypes-inhibit.rs | 17 + src/test/ui/weak-lang-item.rs | 15 + src/test/ui/weak-new-uninhabited-issue-48493.rs | 7 + src/test/ui/weird-exit-code.rs | 28 + src/test/ui/weird-exprs.rs | 180 + src/test/ui/wf-bound-region-in-object-type.rs | 22 + .../ui/where-clauses/auxiliary/where_clauses_xc.rs | 19 + .../where-clause-bounds-inconsistency.rs | 23 + .../where-clause-early-bound-lifetimes.rs | 18 + .../where-clauses/where-clause-region-outlives.rs | 12 + .../ui/where-clauses/where-clauses-cross-crate.rs | 13 + .../ui/where-clauses/where-clauses-lifetimes.rs | 10 + src/test/ui/where-clauses/where-clauses-method.rs | 20 + .../where-clauses-unboxed-closures.rs | 17 + src/test/ui/where-clauses/where-clauses.rs | 27 + src/test/ui/wrapping-int-api.rs | 225 ++ src/test/ui/write-fmt-errors.rs | 46 + src/test/ui/writealias.rs | 19 + src/test/ui/wrong-hashset-issue-42918.rs | 31 + src/test/ui/x86stdcall.rs | 36 + src/test/ui/x86stdcall2.rs | 33 + src/test/ui/yield.rs | 21 + src/test/ui/yield1.rs | 16 + src/test/ui/yield2.rs | 8 + src/test/ui/z-crate-attr.rs | 12 + .../ui/zero-sized/zero-size-type-destructors.rs | 21 + .../ui/zero-sized/zero-sized-binary-heap-push.rs | 20 + .../ui/zero-sized/zero-sized-btreemap-insert.rs | 25 + .../ui/zero-sized/zero-sized-linkedlist-push.rs | 29 + src/test/ui/zero-sized/zero-sized-tuple-struct.rs | 12 + .../ui/zero-sized/zero-sized-vec-deque-push.rs | 32 + src/test/ui/zero-sized/zero-sized-vec-push.rs | 20 + 6440 files changed, 92765 insertions(+), 92897 deletions(-) delete mode 100644 src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-16822.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-18502.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-24106.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/outlive-expansion-phase.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/plugin-args.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs delete mode 100644 src/test/run-pass-fulldeps/compiler-calls.rs delete mode 100644 src/test/run-pass-fulldeps/create-dir-all-bare.rs delete mode 100644 src/test/run-pass-fulldeps/derive-no-std-not-supported.rs delete mode 100644 src/test/run-pass-fulldeps/deriving-encodable-decodable-box.rs delete mode 100644 src/test/run-pass-fulldeps/deriving-encodable-decodable-cell-refcell.rs delete mode 100644 src/test/run-pass-fulldeps/deriving-global.rs delete mode 100644 src/test/run-pass-fulldeps/deriving-hygiene.rs delete mode 100644 src/test/run-pass-fulldeps/dropck_tarena_sound_drop.rs delete mode 100644 src/test/run-pass-fulldeps/empty-struct-braces-derive.rs delete mode 100644 src/test/run-pass-fulldeps/extern-mod-syntax.rs delete mode 100644 src/test/run-pass-fulldeps/issue-11881.rs delete mode 100644 src/test/run-pass-fulldeps/issue-13560.rs delete mode 100644 src/test/run-pass-fulldeps/issue-14021.rs delete mode 100644 src/test/run-pass-fulldeps/issue-15149.rs delete mode 100644 src/test/run-pass-fulldeps/issue-15778-pass.rs delete mode 100644 src/test/run-pass-fulldeps/issue-15924.rs delete mode 100644 src/test/run-pass-fulldeps/issue-16822.rs delete mode 100644 src/test/run-pass-fulldeps/issue-18502.rs delete mode 100644 src/test/run-pass-fulldeps/issue-24106.rs delete mode 100644 src/test/run-pass-fulldeps/issue-24972.rs delete mode 100644 src/test/run-pass-fulldeps/issue-2804.rs delete mode 100644 src/test/run-pass-fulldeps/issue-40001.rs delete mode 100644 src/test/run-pass-fulldeps/issue-4016.rs delete mode 100644 src/test/run-pass-fulldeps/issue-4036.rs delete mode 100644 src/test/run-pass-fulldeps/linkage-visibility.rs delete mode 100644 src/test/run-pass-fulldeps/llvm-pass-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/lto-syntax-extension.rs delete mode 100644 src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs delete mode 100644 src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs delete mode 100644 src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir delete mode 100644 src/test/run-pass-fulldeps/mod_dir_simple/test.rs delete mode 100644 src/test/run-pass-fulldeps/myriad-closures.rs delete mode 100644 src/test/run-pass-fulldeps/newtype_index.rs delete mode 100644 src/test/run-pass-fulldeps/outlive-expansion-phase.rs delete mode 100644 src/test/run-pass-fulldeps/plugin-args-1.rs delete mode 100644 src/test/run-pass-fulldeps/plugin-args-2.rs delete mode 100644 src/test/run-pass-fulldeps/plugin-args-3.rs delete mode 100644 src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs delete mode 100644 src/test/run-pass-fulldeps/regions-mock-tcx.rs delete mode 100644 src/test/run-pass-fulldeps/rename-directory.rs delete mode 100644 src/test/run-pass-fulldeps/roman-numerals-macro.rs delete mode 100644 src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs delete mode 100644 src/test/run-pass-fulldeps/stdio-from.rs delete mode 100644 src/test/run-pass-fulldeps/switch-stdout.rs delete mode 100644 src/test/run-pass-fulldeps/undef_mask.rs delete mode 100644 src/test/run-pass/.gitattributes delete mode 100644 src/test/run-pass/abi-sysv64-arg-passing.rs delete mode 100644 src/test/run-pass/abi-sysv64-register-usage.rs delete mode 100644 src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs delete mode 100644 src/test/run-pass/abort-on-c-abi.rs delete mode 100644 src/test/run-pass/alias-uninit-value.rs delete mode 100644 src/test/run-pass/align-with-extern-c-fn.rs delete mode 100644 src/test/run-pass/alignment-gep-tup-like-1.rs delete mode 100644 src/test/run-pass/alloca-from-derived-tydesc.rs delete mode 100644 src/test/run-pass/allocator-alloc-one.rs delete mode 100644 src/test/run-pass/allocator/auxiliary/custom-as-global.rs delete mode 100644 src/test/run-pass/allocator/auxiliary/custom.rs delete mode 100644 src/test/run-pass/allocator/auxiliary/helper.rs delete mode 100644 src/test/run-pass/allocator/custom-in-block.rs delete mode 100644 src/test/run-pass/allocator/custom-in-submodule.rs delete mode 100644 src/test/run-pass/allocator/custom.rs delete mode 100644 src/test/run-pass/allocator/xcrate-use.rs delete mode 100644 src/test/run-pass/allocator/xcrate-use2.rs delete mode 100644 src/test/run-pass/anon-extern-mod.rs delete mode 100644 src/test/run-pass/argument-passing.rs delete mode 100644 src/test/run-pass/array-slice-vec/arr_cycle.rs delete mode 100644 src/test/run-pass/array-slice-vec/array_const_index-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/box-of-array-of-drop-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/box-of-array-of-drop-2.rs delete mode 100644 src/test/run-pass/array-slice-vec/cast-in-array-size.rs delete mode 100644 src/test/run-pass/array-slice-vec/check-static-mut-slices.rs delete mode 100644 src/test/run-pass/array-slice-vec/check-static-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/copy-out-of-array-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/destructure-array-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/empty-mutable-vec.rs delete mode 100644 src/test/run-pass/array-slice-vec/estr-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/evec-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/fixed_length_copy.rs delete mode 100644 src/test/run-pass/array-slice-vec/huge-largest-array.rs delete mode 100644 src/test/run-pass/array-slice-vec/ivec-pass-by-value.rs delete mode 100644 src/test/run-pass/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs delete mode 100644 src/test/run-pass/array-slice-vec/mutable-alias-vec.rs delete mode 100644 src/test/run-pass/array-slice-vec/nested-vec-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/nested-vec-2.rs delete mode 100644 src/test/run-pass/array-slice-vec/nested-vec-3.rs delete mode 100644 src/test/run-pass/array-slice-vec/new-style-fixed-length-vec.rs delete mode 100644 src/test/run-pass/array-slice-vec/rcvr-borrowed-to-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/repeated-vector-syntax.rs delete mode 100644 src/test/run-pass/array-slice-vec/show-boxed-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice-2.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice-of-zero-size-elements.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice-panic-1.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice-panic-2.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/slice_binary_search.rs delete mode 100644 src/test/run-pass/array-slice-vec/variance-vec-covariant.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-concat.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-dst.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-fixed-length.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-growth.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-late-init.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-macro-no-std.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-macro-repeat.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-macro-rvalue-scope.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-macro-with-brackets.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-macro-with-trailing-comma.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-matching-autoslice.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-matching-fixed.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-matching-fold.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-matching-legal-tail-element-borrow.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-matching.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-push.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-repeat-with-cast.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-slice-drop.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-slice.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-tail-matching.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec-to_str.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec_cycle.rs delete mode 100644 src/test/run-pass/array-slice-vec/vec_cycle_wrapped.rs delete mode 100644 src/test/run-pass/array-slice-vec/vector-no-ann-2.rs delete mode 100644 src/test/run-pass/artificial-block.rs delete mode 100644 src/test/run-pass/as-precedence.rs delete mode 100644 src/test/run-pass/asm-concat-src.rs delete mode 100644 src/test/run-pass/asm-in-moved.rs delete mode 100644 src/test/run-pass/asm-in-out-operand.rs delete mode 100644 src/test/run-pass/asm-indirect-memory.rs delete mode 100644 src/test/run-pass/asm-out-assign.rs delete mode 100644 src/test/run-pass/assert-eq-trailing-comma.rs delete mode 100644 src/test/run-pass/assert-escape.rs delete mode 100644 src/test/run-pass/assert-ne-trailing-comma.rs delete mode 100644 src/test/run-pass/assign-assign.rs delete mode 100644 src/test/run-pass/assoc-oddities-3.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-const-eval.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-cross-crate-const-eval.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-cross-crate-defaults.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-cross-crate.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-in-global-const.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-inherent-impl.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-marks-live-code.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-match-patterns.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-outer-ty-refs.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-overwrite-default.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-public-impl.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-resolution-order.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-self-type.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-type-parameters.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-ufcs-infer-trait.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-use-default.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const-use-impl-of-same-trait.rs delete mode 100644 src/test/run-pass/associated-consts/associated-const.rs delete mode 100644 src/test/run-pass/associated-consts/auxiliary/associated-const-cc-lib.rs delete mode 100644 src/test/run-pass/associated-consts/auxiliary/empty-struct.rs delete mode 100644 src/test/run-pass/associated-item-long-paths.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-basic.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-binding-in-trait.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-bound.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-cc.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-constant-type.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-enum-field-named.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-eq-obj.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-from-supertrait.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-impl-redirect.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-in-default-method.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-in-fn.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-in-impl-generics.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-in-inherent-method.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-issue-20220.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-issue-20371.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-issue-21212.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-iterator-binding.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-method.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-nested-projections.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-ref-from-struct.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-return.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-simple.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-stream.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-struct-field-named.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-sugar-path.rs delete mode 100644 src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs delete mode 100644 src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs delete mode 100644 src/test/run-pass/atomic-access-bool.rs delete mode 100644 src/test/run-pass/atomic-alignment.rs delete mode 100644 src/test/run-pass/atomic-compare_exchange.rs delete mode 100644 src/test/run-pass/atomic-print.rs delete mode 100644 src/test/run-pass/attr-main-2.rs delete mode 100644 src/test/run-pass/attr-main.rs delete mode 100644 src/test/run-pass/attr-shebang.rs delete mode 100644 src/test/run-pass/attr-start.rs delete mode 100644 src/test/run-pass/attr.rs delete mode 100644 src/test/run-pass/augmented-assignments-feature-gate-cross.rs delete mode 100644 src/test/run-pass/augmented-assignments-feature-gate.rs delete mode 100644 src/test/run-pass/auto-instantiate.rs delete mode 100644 src/test/run-pass/auto-is-contextual.rs delete mode 100644 src/test/run-pass/autobind.rs delete mode 100644 src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs delete mode 100644 src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs delete mode 100644 src/test/run-pass/autoref-autoderef/auto-ref.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-method.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoderef-privacy.rs delete mode 100644 src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs delete mode 100644 src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/auxiliary/augmented_assignments.rs delete mode 100644 src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs delete mode 100644 src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs delete mode 100644 src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs delete mode 100644 src/test/run-pass/auxiliary/cond_plugin.rs delete mode 100644 src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs delete mode 100644 src/test/run-pass/auxiliary/debuginfo-lto-aux.rs delete mode 100644 src/test/run-pass/auxiliary/edition-kw-macro-2015.rs delete mode 100644 src/test/run-pass/auxiliary/edition-kw-macro-2018.rs delete mode 100644 src/test/run-pass/auxiliary/foreign_lib.rs delete mode 100644 src/test/run-pass/auxiliary/hello_macro.rs delete mode 100644 src/test/run-pass/auxiliary/impl_privacy_xc_1.rs delete mode 100644 src/test/run-pass/auxiliary/impl_privacy_xc_2.rs delete mode 100644 src/test/run-pass/auxiliary/inline_dtor.rs delete mode 100644 src/test/run-pass/auxiliary/inner_static.rs delete mode 100644 src/test/run-pass/auxiliary/kinds_in_metadata.rs delete mode 100644 src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs delete mode 100644 src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs delete mode 100644 src/test/run-pass/auxiliary/linkage1.rs delete mode 100644 src/test/run-pass/auxiliary/llvm_pr32379.rs delete mode 100644 src/test/run-pass/auxiliary/msvc-data-only-lib.rs delete mode 100644 src/test/run-pass/auxiliary/nested_item.rs delete mode 100644 src/test/run-pass/auxiliary/proc_macro_def.rs delete mode 100644 src/test/run-pass/auxiliary/reachable-unnameable-items.rs delete mode 100644 src/test/run-pass/auxiliary/reexport-should-still-link.rs delete mode 100644 src/test/run-pass/auxiliary/rmeta-rmeta.rs delete mode 100644 src/test/run-pass/auxiliary/svh-a-base.rs delete mode 100644 src/test/run-pass/auxiliary/svh-b.rs delete mode 100644 src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs delete mode 100644 src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs delete mode 100644 src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs delete mode 100644 src/test/run-pass/auxiliary/using-target-feature-unstable.rs delete mode 100644 src/test/run-pass/backtrace-debuginfo-aux.rs delete mode 100644 src/test/run-pass/backtrace-debuginfo.rs delete mode 100644 src/test/run-pass/backtrace.rs delete mode 100644 src/test/run-pass/bare-fn-implements-fn-mut.rs delete mode 100644 src/test/run-pass/bare-static-string.rs delete mode 100644 src/test/run-pass/bench/issue-32062.rs delete mode 100644 src/test/run-pass/big-literals.rs delete mode 100644 src/test/run-pass/binary-minus-without-space.rs delete mode 100644 src/test/run-pass/bind-by-move.rs delete mode 100644 src/test/run-pass/binding/bind-field-short-with-modifiers.rs delete mode 100644 src/test/run-pass/binding/borrowed-ptr-pattern-2.rs delete mode 100644 src/test/run-pass/binding/borrowed-ptr-pattern-3.rs delete mode 100644 src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs delete mode 100644 src/test/run-pass/binding/borrowed-ptr-pattern-option.rs delete mode 100644 src/test/run-pass/binding/borrowed-ptr-pattern.rs delete mode 100644 src/test/run-pass/binding/empty-types-in-patterns.rs delete mode 100644 src/test/run-pass/binding/exhaustive-bool-match-sanity.rs delete mode 100644 src/test/run-pass/binding/expr-match-generic-unique1.rs delete mode 100644 src/test/run-pass/binding/expr-match-generic-unique2.rs delete mode 100644 src/test/run-pass/binding/expr-match-generic.rs delete mode 100644 src/test/run-pass/binding/expr-match-panic-all.rs delete mode 100644 src/test/run-pass/binding/expr-match-panic.rs delete mode 100644 src/test/run-pass/binding/expr-match-unique.rs delete mode 100644 src/test/run-pass/binding/expr-match.rs delete mode 100644 src/test/run-pass/binding/fat-arrow-match.rs delete mode 100644 src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs delete mode 100644 src/test/run-pass/binding/fn-pattern-expected-type-2.rs delete mode 100644 src/test/run-pass/binding/fn-pattern-expected-type.rs delete mode 100644 src/test/run-pass/binding/func-arg-incomplete-pattern.rs delete mode 100644 src/test/run-pass/binding/func-arg-ref-pattern.rs delete mode 100644 src/test/run-pass/binding/func-arg-wild-pattern.rs delete mode 100644 src/test/run-pass/binding/if-let.rs delete mode 100644 src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs delete mode 100644 src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs delete mode 100644 src/test/run-pass/binding/irrefutable-slice-patterns.rs delete mode 100644 src/test/run-pass/binding/let-assignability.rs delete mode 100644 src/test/run-pass/binding/let-destruct-ref.rs delete mode 100644 src/test/run-pass/binding/let-var-hygiene.rs delete mode 100644 src/test/run-pass/binding/match-arm-statics.rs delete mode 100644 src/test/run-pass/binding/match-beginning-vert.rs delete mode 100644 src/test/run-pass/binding/match-borrowed_str.rs delete mode 100644 src/test/run-pass/binding/match-bot-2.rs delete mode 100644 src/test/run-pass/binding/match-bot.rs delete mode 100644 src/test/run-pass/binding/match-byte-array-patterns.rs delete mode 100644 src/test/run-pass/binding/match-enum-struct-0.rs delete mode 100644 src/test/run-pass/binding/match-enum-struct-1.rs delete mode 100644 src/test/run-pass/binding/match-implicit-copy-unique.rs delete mode 100644 src/test/run-pass/binding/match-in-macro.rs delete mode 100644 src/test/run-pass/binding/match-join.rs delete mode 100644 src/test/run-pass/binding/match-larger-const.rs delete mode 100644 src/test/run-pass/binding/match-naked-record-expr.rs delete mode 100644 src/test/run-pass/binding/match-naked-record.rs delete mode 100644 src/test/run-pass/binding/match-path.rs delete mode 100644 src/test/run-pass/binding/match-pattern-bindings.rs delete mode 100644 src/test/run-pass/binding/match-pattern-lit.rs delete mode 100644 src/test/run-pass/binding/match-pattern-no-type-params.rs delete mode 100644 src/test/run-pass/binding/match-pattern-simple.rs delete mode 100644 src/test/run-pass/binding/match-phi.rs delete mode 100644 src/test/run-pass/binding/match-pipe-binding.rs delete mode 100644 src/test/run-pass/binding/match-range-infer.rs delete mode 100644 src/test/run-pass/binding/match-range-static.rs delete mode 100644 src/test/run-pass/binding/match-range.rs delete mode 100644 src/test/run-pass/binding/match-reassign.rs delete mode 100644 src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs delete mode 100644 src/test/run-pass/binding/match-ref-binding-mut-option.rs delete mode 100644 src/test/run-pass/binding/match-ref-binding-mut.rs delete mode 100644 src/test/run-pass/binding/match-ref-binding.rs delete mode 100644 src/test/run-pass/binding/match-ref-unsized.rs delete mode 100644 src/test/run-pass/binding/match-str.rs delete mode 100644 src/test/run-pass/binding/match-struct-0.rs delete mode 100644 src/test/run-pass/binding/match-tag.rs delete mode 100644 src/test/run-pass/binding/match-unique-bind.rs delete mode 100644 src/test/run-pass/binding/match-unsized.rs delete mode 100644 src/test/run-pass/binding/match-value-binding-in-guard-3291.rs delete mode 100644 src/test/run-pass/binding/match-var-hygiene.rs delete mode 100644 src/test/run-pass/binding/match-vec-alternatives.rs delete mode 100644 src/test/run-pass/binding/match-vec-rvalue.rs delete mode 100644 src/test/run-pass/binding/match-with-ret-arm.rs delete mode 100644 src/test/run-pass/binding/multi-let.rs delete mode 100644 src/test/run-pass/binding/mut-in-ident-patterns.rs delete mode 100644 src/test/run-pass/binding/nested-exhaustive-match.rs delete mode 100644 src/test/run-pass/binding/nested-matchs.rs delete mode 100644 src/test/run-pass/binding/nested-pattern.rs delete mode 100644 src/test/run-pass/binding/nil-pattern.rs delete mode 100644 src/test/run-pass/binding/nullary-or-pattern.rs delete mode 100644 src/test/run-pass/binding/optional_comma_in_match_arm.rs delete mode 100644 src/test/run-pass/binding/or-pattern.rs delete mode 100644 src/test/run-pass/binding/order-drop-with-match.rs delete mode 100644 src/test/run-pass/binding/pat-ranges.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-1.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-2.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-3.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-4.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-5.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-6.rs delete mode 100644 src/test/run-pass/binding/pat-tuple-7.rs delete mode 100644 src/test/run-pass/binding/pattern-bound-var-in-for-each.rs delete mode 100644 src/test/run-pass/binding/pattern-in-closure.rs delete mode 100644 src/test/run-pass/binding/range-inclusive-pattern-precedence.rs delete mode 100644 src/test/run-pass/binding/simple-generic-match.rs delete mode 100644 src/test/run-pass/binding/use-uninit-match.rs delete mode 100644 src/test/run-pass/binding/use-uninit-match2.rs delete mode 100644 src/test/run-pass/binding/zero_sized_subslice_match.rs delete mode 100644 src/test/run-pass/binops-issue-22743.rs delete mode 100644 src/test/run-pass/binops.rs delete mode 100644 src/test/run-pass/bitwise.rs delete mode 100644 src/test/run-pass/blind-item-local-shadow.rs delete mode 100644 src/test/run-pass/blind-item-mixed-crate-use-item.rs delete mode 100644 src/test/run-pass/blind-item-mixed-use-item.rs delete mode 100644 src/test/run-pass/block-arg-call-as.rs delete mode 100644 src/test/run-pass/block-arg.rs delete mode 100644 src/test/run-pass/block-explicit-types.rs delete mode 100644 src/test/run-pass/block-expr-precedence.rs delete mode 100644 src/test/run-pass/block-fn-coerce.rs delete mode 100644 src/test/run-pass/block-iter-1.rs delete mode 100644 src/test/run-pass/block-iter-2.rs delete mode 100644 src/test/run-pass/bool-not.rs delete mode 100644 src/test/run-pass/bool.rs delete mode 100644 src/test/run-pass/borrow-by-val-method-receiver.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-binding-mutbl.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-closures-two-imm.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-lend-args.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-mut-uniq.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-pat-enum.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-trait-lifetime.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-univariant-enum.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs delete mode 100644 src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs delete mode 100644 src/test/run-pass/borrowck/issue-62007-assign-box.rs delete mode 100644 src/test/run-pass/borrowck/issue-62007-assign-field.rs delete mode 100644 src/test/run-pass/borrowck/two-phase-baseline.rs delete mode 100644 src/test/run-pass/borrowck/two-phase-bin-ops.rs delete mode 100644 src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs delete mode 100644 src/test/run-pass/box-new.rs delete mode 100644 src/test/run-pass/bug-7183-generics.rs delete mode 100644 src/test/run-pass/bug-7295.rs delete mode 100644 src/test/run-pass/builtin-clone-unwind.rs delete mode 100644 src/test/run-pass/builtin-clone.rs delete mode 100644 src/test/run-pass/builtin-superkinds-capabilities-transitive.rs delete mode 100644 src/test/run-pass/builtin-superkinds-capabilities-xc.rs delete mode 100644 src/test/run-pass/builtin-superkinds-capabilities.rs delete mode 100644 src/test/run-pass/builtin-superkinds-in-metadata.rs delete mode 100644 src/test/run-pass/builtin-superkinds-phantom-typaram.rs delete mode 100644 src/test/run-pass/builtin-superkinds-simple.rs delete mode 100644 src/test/run-pass/builtin-superkinds-typaram.rs delete mode 100644 src/test/run-pass/byte-literals.rs delete mode 100644 src/test/run-pass/c-stack-as-value.rs delete mode 100644 src/test/run-pass/c-stack-returning-int64.rs delete mode 100644 src/test/run-pass/cabi-int-widening.rs delete mode 100644 src/test/run-pass/can-copy-pod.rs delete mode 100644 src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs delete mode 100644 src/test/run-pass/cast-does-fallback.rs delete mode 100644 src/test/run-pass/cast-region-to-uint.rs delete mode 100644 src/test/run-pass/cast-rfc0401-vtable-kinds.rs delete mode 100644 src/test/run-pass/cast-rfc0401.rs delete mode 100644 src/test/run-pass/cast-to-infer-ty.rs delete mode 100644 src/test/run-pass/cast.rs delete mode 100644 src/test/run-pass/catch-unwind-bang.rs delete mode 100644 src/test/run-pass/cell-does-not-clone.rs delete mode 100644 src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs delete mode 100644 src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs delete mode 100644 src/test/run-pass/cfg/cfg-attr-cfg.rs delete mode 100644 src/test/run-pass/cfg/cfg-attr-crate.rs delete mode 100644 src/test/run-pass/cfg/cfg-family.rs delete mode 100644 src/test/run-pass/cfg/cfg-in-crate-1.rs delete mode 100644 src/test/run-pass/cfg/cfg-macros-foo.rs delete mode 100644 src/test/run-pass/cfg/cfg-macros-notfoo.rs delete mode 100644 src/test/run-pass/cfg/cfg-match-arm.rs delete mode 100644 src/test/run-pass/cfg/cfg-target-family.rs delete mode 100644 src/test/run-pass/cfg/cfg-target-vendor.rs delete mode 100644 src/test/run-pass/cfg/cfg_attr.rs delete mode 100644 src/test/run-pass/cfg/cfg_inner_static.rs delete mode 100644 src/test/run-pass/cfg/cfg_stmt_expr.rs delete mode 100644 src/test/run-pass/cfg/cfgs-on-items.rs delete mode 100644 src/test/run-pass/cfg/conditional-compile-arch.rs delete mode 100644 src/test/run-pass/cfg/conditional-compile.rs delete mode 100644 src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs delete mode 100644 src/test/run-pass/chalkify/builtin-copy-clone.rs delete mode 100644 src/test/run-pass/chalkify/inherent_impl.rs delete mode 100644 src/test/run-pass/chalkify/projection.rs delete mode 100644 src/test/run-pass/chalkify/super_trait.rs delete mode 100644 src/test/run-pass/chalkify/trait_implied_bound.rs delete mode 100644 src/test/run-pass/chalkify/type_implied_bound.rs delete mode 100644 src/test/run-pass/char.rs delete mode 100644 src/test/run-pass/char_unicode.rs delete mode 100644 src/test/run-pass/check-static-recursion-foreign.rs delete mode 100644 src/test/run-pass/check_const-feature-gated.rs delete mode 100644 src/test/run-pass/child-outlives-parent.rs delete mode 100644 src/test/run-pass/cleanup-arm-conditional.rs delete mode 100644 src/test/run-pass/cleanup-rvalue-during-if-and-while.rs delete mode 100644 src/test/run-pass/cleanup-rvalue-for-scope.rs delete mode 100644 src/test/run-pass/cleanup-rvalue-scopes.rs delete mode 100644 src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs delete mode 100644 src/test/run-pass/cleanup-shortcircuit.rs delete mode 100644 src/test/run-pass/clone-with-exterior.rs delete mode 100644 src/test/run-pass/close-over-big-then-small-data.rs delete mode 100644 src/test/run-pass/cmp-default.rs delete mode 100644 src/test/run-pass/codegen-object-shim.rs delete mode 100644 src/test/run-pass/coerce/coerce-expect-unsized.rs delete mode 100644 src/test/run-pass/coerce/coerce-overloaded-autoderef.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs delete mode 100644 src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs delete mode 100644 src/test/run-pass/coerce/coerce-unify-return.rs delete mode 100644 src/test/run-pass/coerce/coerce-unify.rs delete mode 100644 src/test/run-pass/coerce/coerce-unsize-subtype.rs delete mode 100644 src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs delete mode 100644 src/test/run-pass/coherence/coherence-bigint-int.rs delete mode 100644 src/test/run-pass/coherence/coherence-bigint-vecint.rs delete mode 100644 src/test/run-pass/coherence/coherence-blanket.rs delete mode 100644 src/test/run-pass/coherence/coherence-covered-type-parameter.rs delete mode 100644 src/test/run-pass/coherence/coherence-impl-in-fn.rs delete mode 100644 src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs delete mode 100644 src/test/run-pass/coherence/coherence-iterator-vec.rs delete mode 100644 src/test/run-pass/coherence/coherence-multidispatch-tuple.rs delete mode 100644 src/test/run-pass/coherence/coherence-rfc447-constrained.rs delete mode 100644 src/test/run-pass/coherence/coherence-where-clause.rs delete mode 100644 src/test/run-pass/coherence/coherence_copy_like.rs delete mode 100644 src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs delete mode 100644 src/test/run-pass/collections-const-new.rs delete mode 100644 src/test/run-pass/command-exec.rs delete mode 100644 src/test/run-pass/command-pre-exec.rs delete mode 100644 src/test/run-pass/command-uid-gid.rs delete mode 100644 src/test/run-pass/complex.rs delete mode 100644 src/test/run-pass/consts/assoc-const.rs delete mode 100644 src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs delete mode 100644 src/test/run-pass/consts/auxiliary/cci_const.rs delete mode 100644 src/test/run-pass/consts/auxiliary/cci_const_block.rs delete mode 100644 src/test/run-pass/consts/bswap-const.rs delete mode 100644 src/test/run-pass/consts/chained-constants-stackoverflow.rs delete mode 100644 src/test/run-pass/consts/const-adt-align-mismatch.rs delete mode 100644 src/test/run-pass/consts/const-autoderef.rs delete mode 100644 src/test/run-pass/consts/const-big-enum.rs delete mode 100644 src/test/run-pass/consts/const-binops.rs delete mode 100644 src/test/run-pass/consts/const-bitshift-rhs-inference.rs delete mode 100644 src/test/run-pass/consts/const-block-cross-crate-fn.rs delete mode 100644 src/test/run-pass/consts/const-block-item-macro-codegen.rs delete mode 100644 src/test/run-pass/consts/const-block-item.rs delete mode 100644 src/test/run-pass/consts/const-block-non-item-statement-3.rs delete mode 100644 src/test/run-pass/consts/const-block.rs delete mode 100644 src/test/run-pass/consts/const-bound.rs delete mode 100644 src/test/run-pass/consts/const-byte-str-cast.rs delete mode 100644 src/test/run-pass/consts/const-cast-ptr-int.rs delete mode 100644 src/test/run-pass/consts/const-cast.rs delete mode 100644 src/test/run-pass/consts/const-const.rs delete mode 100644 src/test/run-pass/consts/const-contents.rs delete mode 100644 src/test/run-pass/consts/const-cross-crate-const.rs delete mode 100644 src/test/run-pass/consts/const-cross-crate-extern.rs delete mode 100644 src/test/run-pass/consts/const-deref.rs delete mode 100644 src/test/run-pass/consts/const-endianess.rs delete mode 100644 src/test/run-pass/consts/const-enum-byref-self.rs delete mode 100644 src/test/run-pass/consts/const-enum-byref.rs delete mode 100644 src/test/run-pass/consts/const-enum-cast.rs delete mode 100644 src/test/run-pass/consts/const-enum-ptr.rs delete mode 100644 src/test/run-pass/consts/const-enum-struct.rs delete mode 100644 src/test/run-pass/consts/const-enum-struct2.rs delete mode 100644 src/test/run-pass/consts/const-enum-structlike.rs delete mode 100644 src/test/run-pass/consts/const-enum-tuple.rs delete mode 100644 src/test/run-pass/consts/const-enum-tuple2.rs delete mode 100644 src/test/run-pass/consts/const-enum-tuplestruct.rs delete mode 100644 src/test/run-pass/consts/const-enum-tuplestruct2.rs delete mode 100644 src/test/run-pass/consts/const-enum-vec-index.rs delete mode 100644 src/test/run-pass/consts/const-enum-vec-ptr.rs delete mode 100644 src/test/run-pass/consts/const-enum-vector.rs delete mode 100644 src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs delete mode 100644 src/test/run-pass/consts/const-expr-in-vec-repeat.rs delete mode 100644 src/test/run-pass/consts/const-extern-function.rs delete mode 100644 src/test/run-pass/consts/const-fields-and-indexing.rs delete mode 100644 src/test/run-pass/consts/const-fn-const-eval.rs delete mode 100644 src/test/run-pass/consts/const-fn-feature-flags.rs delete mode 100644 src/test/run-pass/consts/const-fn-method.rs delete mode 100644 src/test/run-pass/consts/const-fn-nested.rs delete mode 100644 src/test/run-pass/consts/const-fn-stability-calls.rs delete mode 100644 src/test/run-pass/consts/const-fn-type-name.rs delete mode 100644 src/test/run-pass/consts/const-fn-val.rs delete mode 100644 src/test/run-pass/consts/const-fn.rs delete mode 100644 src/test/run-pass/consts/const-index-feature-gate.rs delete mode 100644 src/test/run-pass/consts/const-int-saturating-arith.rs delete mode 100644 src/test/run-pass/consts/const-meth-pattern.rs delete mode 100644 src/test/run-pass/consts/const-needs_drop.rs delete mode 100644 src/test/run-pass/consts/const-negation.rs delete mode 100644 src/test/run-pass/consts/const-negative.rs delete mode 100644 src/test/run-pass/consts/const-nullary-enum.rs delete mode 100644 src/test/run-pass/consts/const-nullary-univariant-enum.rs delete mode 100644 src/test/run-pass/consts/const-pattern-variant.rs delete mode 100644 src/test/run-pass/consts/const-rec-and-tup.rs delete mode 100644 src/test/run-pass/consts/const-region-ptrs-noncopy.rs delete mode 100644 src/test/run-pass/consts/const-region-ptrs.rs delete mode 100644 src/test/run-pass/consts/const-repeated-values.rs delete mode 100644 src/test/run-pass/consts/const-size_of-align_of.rs delete mode 100644 src/test/run-pass/consts/const-str-ptr.rs delete mode 100644 src/test/run-pass/consts/const-struct-offsets.rs delete mode 100644 src/test/run-pass/consts/const-struct.rs delete mode 100644 src/test/run-pass/consts/const-trait-to-trait.rs delete mode 100644 src/test/run-pass/consts/const-tuple-struct.rs delete mode 100644 src/test/run-pass/consts/const-unit-struct.rs delete mode 100644 src/test/run-pass/consts/const-unsafe-fn.rs delete mode 100644 src/test/run-pass/consts/const-vec-of-fns.rs delete mode 100644 src/test/run-pass/consts/const-vec-syntax.rs delete mode 100644 src/test/run-pass/consts/const-vecs-and-slices.rs delete mode 100644 src/test/run-pass/consts/const.rs delete mode 100644 src/test/run-pass/consts/consts-in-patterns.rs delete mode 100644 src/test/run-pass/consts/deref_in_pattern.rs delete mode 100644 src/test/run-pass/consts/ice-48279.rs delete mode 100644 src/test/run-pass/consts/issue-37550.rs delete mode 100644 src/test/run-pass/consts/issue-broken-mir.rs delete mode 100644 src/test/run-pass/consts/locals-in-const-fn.rs delete mode 100644 src/test/run-pass/consts/match-const-fn-structs.rs delete mode 100644 src/test/run-pass/consts/mozjs-error.rs delete mode 100644 src/test/run-pass/consts/non-scalar-cast.rs delete mode 100644 src/test/run-pass/consts/promotion.rs delete mode 100644 src/test/run-pass/consts/references.rs delete mode 100644 src/test/run-pass/consts/repeat_match.rs delete mode 100644 src/test/run-pass/consts/return-in-const-fn.rs delete mode 100644 src/test/run-pass/consts/signed_enum_discr.rs delete mode 100644 src/test/run-pass/consts/transmute-const.rs delete mode 100644 src/test/run-pass/consts/tuple-struct-constructors.rs delete mode 100644 src/test/run-pass/core-run-destroy.rs delete mode 100644 src/test/run-pass/crate-leading-sep.rs delete mode 100644 src/test/run-pass/crate-method-reexport-grrrrrrr.rs delete mode 100644 src/test/run-pass/crate-name-attr-used.rs delete mode 100644 src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_const.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs delete mode 100644 src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs delete mode 100644 src/test/run-pass/cross-crate/cci_borrow.rs delete mode 100644 src/test/run-pass/cross-crate/cci_capture_clause.rs delete mode 100644 src/test/run-pass/cross-crate/cci_impl_exe.rs delete mode 100644 src/test/run-pass/cross-crate/cci_iter_exe.rs delete mode 100644 src/test/run-pass/cross-crate/cci_nested_exe.rs delete mode 100644 src/test/run-pass/cross-crate/cci_no_inline_exe.rs delete mode 100644 src/test/run-pass/cross-crate/cross-crate-const-pat.rs delete mode 100644 src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs delete mode 100644 src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs delete mode 100644 src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs delete mode 100644 src/test/run-pass/cross-crate/static-array-across-crate.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate-address-insignificant.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate-static-addresses.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate-unit-struct.rs delete mode 100644 src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs delete mode 100644 src/test/run-pass/crt-static-off-works.rs delete mode 100644 src/test/run-pass/crt-static-on-works.rs delete mode 100644 src/test/run-pass/cycle-generic-bound.rs delete mode 100644 src/test/run-pass/dead-code-alias-in-pat.rs delete mode 100644 src/test/run-pass/dead-code-leading-underscore.rs delete mode 100644 src/test/run-pass/debuginfo-lto.rs delete mode 100644 src/test/run-pass/deep.rs delete mode 100644 src/test/run-pass/default-alloc-error-hook.rs delete mode 100644 src/test/run-pass/default-associated-types.rs delete mode 100644 src/test/run-pass/default-method-parsing.rs delete mode 100644 src/test/run-pass/default-method-simple.rs delete mode 100644 src/test/run-pass/defaults-well-formedness.rs delete mode 100644 src/test/run-pass/deprecation-in-force-unstable.rs delete mode 100644 src/test/run-pass/deref-lval.rs delete mode 100644 src/test/run-pass/deref-mut-on-ref.rs delete mode 100644 src/test/run-pass/deref-on-ref.rs delete mode 100644 src/test/run-pass/deref-rc.rs delete mode 100644 src/test/run-pass/deref.rs delete mode 100644 src/test/run-pass/deriving/auxiliary/derive-no-std.rs delete mode 100644 src/test/run-pass/deriving/derive-no-std.rs delete mode 100644 src/test/run-pass/deriving/derive-partialord-correctness.rs delete mode 100644 src/test/run-pass/deriving/deriving-associated-types.rs delete mode 100644 src/test/run-pass/deriving/deriving-bounds.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-array.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-generic-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-generic-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-clone-tuple-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-cmp-generic-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-cmp-generic-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs delete mode 100644 src/test/run-pass/deriving/deriving-copyclone.rs delete mode 100644 src/test/run-pass/deriving/deriving-default-box.rs delete mode 100644 src/test/run-pass/deriving/deriving-enum-single-variant.rs delete mode 100644 src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs delete mode 100644 src/test/run-pass/deriving/deriving-hash.rs delete mode 100644 src/test/run-pass/deriving/deriving-in-fn.rs delete mode 100644 src/test/run-pass/deriving/deriving-in-macro.rs delete mode 100644 src/test/run-pass/deriving/deriving-meta-multiple.rs delete mode 100644 src/test/run-pass/deriving/deriving-meta.rs delete mode 100644 src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs delete mode 100644 src/test/run-pass/deriving/deriving-show-2.rs delete mode 100644 src/test/run-pass/deriving/deriving-show.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-c-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-struct.rs delete mode 100644 src/test/run-pass/deriving/deriving-via-extension-type-params.rs delete mode 100644 src/test/run-pass/deriving/deriving-with-repr-packed.rs delete mode 100644 src/test/run-pass/dispatch_from_dyn_zst.rs delete mode 100644 src/test/run-pass/diverging-fallback-control-flow.rs delete mode 100644 src/test/run-pass/diverging-fallback-method-chain.rs delete mode 100644 src/test/run-pass/diverging-fallback-option.rs delete mode 100644 src/test/run-pass/double-ref.rs delete mode 100644 src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs delete mode 100644 src/test/run-pass/drop/drop-on-empty-block-exit.rs delete mode 100644 src/test/run-pass/drop/drop-on-ret.rs delete mode 100644 src/test/run-pass/drop/drop-struct-as-object.rs delete mode 100644 src/test/run-pass/drop/drop-trait-enum.rs delete mode 100644 src/test/run-pass/drop/drop-trait-generic.rs delete mode 100644 src/test/run-pass/drop/drop-trait.rs delete mode 100644 src/test/run-pass/drop/drop-uninhabited-enum.rs delete mode 100644 src/test/run-pass/drop/drop-with-type-ascription-1.rs delete mode 100644 src/test/run-pass/drop/drop-with-type-ascription-2.rs delete mode 100644 src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs delete mode 100644 src/test/run-pass/drop/dropck-eyepatch-reorder.rs delete mode 100644 src/test/run-pass/drop/dropck-eyepatch.rs delete mode 100644 src/test/run-pass/drop/dropck_legal_cycles.rs delete mode 100644 src/test/run-pass/drop/dynamic-drop-async.rs delete mode 100644 src/test/run-pass/drop/dynamic-drop.rs delete mode 100644 src/test/run-pass/drop/no-drop-flag-size.rs delete mode 100644 src/test/run-pass/drop/nondrop-cycle.rs delete mode 100644 src/test/run-pass/dupe-first-attr.rc delete mode 100644 src/test/run-pass/duplicated-external-mods.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-coercions.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-deref.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-field-align.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-index.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-raw.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-struct.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-trait.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs delete mode 100644 src/test/run-pass/dynamically-sized-types/dst-tuple.rs delete mode 100644 src/test/run-pass/early-ret-binop-add.rs delete mode 100644 src/test/run-pass/early-vtbl-resolution.rs delete mode 100644 src/test/run-pass/edition-keywords-2015-2015.rs delete mode 100644 src/test/run-pass/edition-keywords-2015-2018.rs delete mode 100644 src/test/run-pass/edition-keywords-2018-2015.rs delete mode 100644 src/test/run-pass/edition-keywords-2018-2018.rs delete mode 100644 src/test/run-pass/else-if.rs delete mode 100644 src/test/run-pass/empty-allocation-non-null.rs delete mode 100644 src/test/run-pass/empty-allocation-rvalue-non-null.rs delete mode 100644 src/test/run-pass/empty-type-parameter-list.rs delete mode 100644 src/test/run-pass/empty_global_asm.rs delete mode 100644 src/test/run-pass/env-args-reverse-iterator.rs delete mode 100644 src/test/run-pass/env-funky-keys.rs delete mode 100644 src/test/run-pass/env-home-dir.rs delete mode 100644 src/test/run-pass/env-null-vars.rs delete mode 100644 src/test/run-pass/env-vars.rs delete mode 100644 src/test/run-pass/epoch-gate-feature.rs delete mode 100644 src/test/run-pass/eq-multidispatch.rs delete mode 100644 src/test/run-pass/estr-uniq.rs delete mode 100644 src/test/run-pass/exec-env.rs delete mode 100644 src/test/run-pass/existential_type.rs delete mode 100644 src/test/run-pass/explicit-i-suffix.rs delete mode 100644 src/test/run-pass/export-glob-imports-target.rs delete mode 100644 src/test/run-pass/export-multi.rs delete mode 100644 src/test/run-pass/export-non-interference2.rs delete mode 100644 src/test/run-pass/export-non-interference3.rs delete mode 100644 src/test/run-pass/expr-block-fn.rs delete mode 100644 src/test/run-pass/expr-block-generic-unique1.rs delete mode 100644 src/test/run-pass/expr-block-generic-unique2.rs delete mode 100644 src/test/run-pass/expr-block-generic.rs delete mode 100644 src/test/run-pass/expr-block-slot.rs delete mode 100644 src/test/run-pass/expr-block-unique.rs delete mode 100644 src/test/run-pass/expr-block.rs delete mode 100644 src/test/run-pass/expr-copy.rs delete mode 100644 src/test/run-pass/expr-empty-ret.rs delete mode 100644 src/test/run-pass/expr-fn.rs delete mode 100644 src/test/run-pass/expr-if-generic.rs delete mode 100644 src/test/run-pass/expr-if-panic-all.rs delete mode 100644 src/test/run-pass/expr-if-panic.rs delete mode 100644 src/test/run-pass/expr-if-unique.rs delete mode 100644 src/test/run-pass/expr-if.rs delete mode 100644 src/test/run-pass/expr-scope.rs delete mode 100644 src/test/run-pass/ext-expand-inner-exprs.rs delete mode 100644 src/test/run-pass/extend-for-unit.rs delete mode 100644 src/test/run-pass/exterior.rs delete mode 100644 src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs delete mode 100644 src/test/run-pass/extern/auxiliary/extern-take-value.rs delete mode 100644 src/test/run-pass/extern/auxiliary/extern_calling_convention.rs delete mode 100644 src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs delete mode 100644 src/test/run-pass/extern/auxiliary/fat_drop.rs delete mode 100644 src/test/run-pass/extern/extern-1.rs delete mode 100644 src/test/run-pass/extern/extern-call-deep.rs delete mode 100644 src/test/run-pass/extern/extern-call-deep2.rs delete mode 100644 src/test/run-pass/extern/extern-call-direct.rs delete mode 100644 src/test/run-pass/extern/extern-call-indirect.rs delete mode 100644 src/test/run-pass/extern/extern-call-scrub.rs delete mode 100644 src/test/run-pass/extern/extern-calling-convention-test.rs delete mode 100644 src/test/run-pass/extern/extern-compare-with-return-type.rs delete mode 100644 src/test/run-pass/extern/extern-crosscrate.rs delete mode 100644 src/test/run-pass/extern/extern-foreign-crate.rs delete mode 100644 src/test/run-pass/extern/extern-methods.rs delete mode 100644 src/test/run-pass/extern/extern-mod-abi.rs delete mode 100644 src/test/run-pass/extern/extern-mod-ordering-exe.rs delete mode 100644 src/test/run-pass/extern/extern-pass-TwoU16s.rs delete mode 100644 src/test/run-pass/extern/extern-pass-TwoU32s.rs delete mode 100644 src/test/run-pass/extern/extern-pass-TwoU64s.rs delete mode 100644 src/test/run-pass/extern/extern-pass-TwoU8s.rs delete mode 100644 src/test/run-pass/extern/extern-pass-char.rs delete mode 100644 src/test/run-pass/extern/extern-pass-double.rs delete mode 100644 src/test/run-pass/extern/extern-pass-empty.rs delete mode 100644 src/test/run-pass/extern/extern-pass-u32.rs delete mode 100644 src/test/run-pass/extern/extern-pass-u64.rs delete mode 100644 src/test/run-pass/extern/extern-prelude-core.rs delete mode 100644 src/test/run-pass/extern/extern-prelude-core.stderr delete mode 100644 src/test/run-pass/extern/extern-prelude-no-speculative.rs delete mode 100644 src/test/run-pass/extern/extern-prelude-std.rs delete mode 100644 src/test/run-pass/extern/extern-prelude-std.stderr delete mode 100644 src/test/run-pass/extern/extern-pub.rs delete mode 100644 src/test/run-pass/extern/extern-return-TwoU16s.rs delete mode 100644 src/test/run-pass/extern/extern-return-TwoU32s.rs delete mode 100644 src/test/run-pass/extern/extern-return-TwoU64s.rs delete mode 100644 src/test/run-pass/extern/extern-return-TwoU8s.rs delete mode 100644 src/test/run-pass/extern/extern-rust.rs delete mode 100644 src/test/run-pass/extern/extern-take-value.rs delete mode 100644 src/test/run-pass/extern/extern-thiscall.rs delete mode 100644 src/test/run-pass/extern/extern-types-inherent-impl.rs delete mode 100644 src/test/run-pass/extern/extern-types-manual-sync-send.rs delete mode 100644 src/test/run-pass/extern/extern-types-pointer-cast.rs delete mode 100644 src/test/run-pass/extern/extern-types-size_of_val.rs delete mode 100644 src/test/run-pass/extern/extern-types-thin-pointer.rs delete mode 100644 src/test/run-pass/extern/extern-types-trait-impl.rs delete mode 100644 src/test/run-pass/extern/extern-vectorcall.rs delete mode 100644 src/test/run-pass/extern/extern_fat_drop.rs delete mode 100644 src/test/run-pass/extoption_env-not-defined.rs delete mode 100644 src/test/run-pass/fact.rs delete mode 100644 src/test/run-pass/fat-lto.rs delete mode 100644 src/test/run-pass/fds-are-cloexec.rs delete mode 100644 src/test/run-pass/filter-block-view-items.rs delete mode 100644 src/test/run-pass/fixup-deref-mut.rs delete mode 100644 src/test/run-pass/for-loop-while/auto-loop.rs delete mode 100644 src/test/run-pass/for-loop-while/break-value.rs delete mode 100644 src/test/run-pass/for-loop-while/break.rs delete mode 100644 src/test/run-pass/for-loop-while/for-destruct.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-goofiness.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-into-iterator.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-macro.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-no-std.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-panic.rs delete mode 100644 src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-external-iterators.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-nested.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-put-structured.rs delete mode 100644 src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs delete mode 100644 src/test/run-pass/for-loop-while/label_break_value.rs delete mode 100644 src/test/run-pass/for-loop-while/labeled-break.rs delete mode 100644 src/test/run-pass/for-loop-while/linear-for-loop.rs delete mode 100644 src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs delete mode 100644 src/test/run-pass/for-loop-while/liveness-loop-break.rs delete mode 100644 src/test/run-pass/for-loop-while/liveness-move-in-loop.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-break-cont-1.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-break-cont.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-break-value.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-diverges.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-label-shadowing.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-labeled-break-value.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs delete mode 100644 src/test/run-pass/for-loop-while/loop-scope.rs delete mode 100644 src/test/run-pass/for-loop-while/while-cont.rs delete mode 100644 src/test/run-pass/for-loop-while/while-flow-graph.rs delete mode 100644 src/test/run-pass/for-loop-while/while-label.rs delete mode 100644 src/test/run-pass/for-loop-while/while-let.rs delete mode 100644 src/test/run-pass/for-loop-while/while-loop-constraints-2.rs delete mode 100644 src/test/run-pass/for-loop-while/while-prelude-drop.rs delete mode 100644 src/test/run-pass/for-loop-while/while-with-break.rs delete mode 100644 src/test/run-pass/for-loop-while/while.rs delete mode 100644 src/test/run-pass/foreign/auxiliary/fn-abi.rs delete mode 100644 src/test/run-pass/foreign/auxiliary/foreign_lib.rs delete mode 100644 src/test/run-pass/foreign/foreign-call-no-runtime.rs delete mode 100644 src/test/run-pass/foreign/foreign-dupe.rs delete mode 100644 src/test/run-pass/foreign/foreign-fn-linkname.rs delete mode 100644 src/test/run-pass/foreign/foreign-fn-with-byval.rs delete mode 100644 src/test/run-pass/foreign/foreign-int-types.rs delete mode 100644 src/test/run-pass/foreign/foreign-mod-src/compiletest-ignore-dir delete mode 100644 src/test/run-pass/foreign/foreign-mod-src/inner.rs delete mode 100644 src/test/run-pass/foreign/foreign-mod-unused-const.rs delete mode 100644 src/test/run-pass/foreign/foreign-no-abi.rs delete mode 100644 src/test/run-pass/foreign/foreign-src/compiletest-ignore-dir delete mode 100644 src/test/run-pass/foreign/foreign-src/foreign.rs delete mode 100644 src/test/run-pass/foreign/foreign-truncated-arguments.rs delete mode 100644 src/test/run-pass/foreign/foreign2.rs delete mode 100644 src/test/run-pass/format-hygiene.rs delete mode 100644 src/test/run-pass/format-nan.rs delete mode 100644 src/test/run-pass/format-no-std.rs delete mode 100644 src/test/run-pass/format-ref-cell.rs delete mode 100644 src/test/run-pass/fsu-moves-and-copies.rs delete mode 100644 src/test/run-pass/fun-call-variants.rs delete mode 100644 src/test/run-pass/fun-indirect-call.rs delete mode 100644 src/test/run-pass/functions-closures/auxiliary/fn-abi.rs delete mode 100644 src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs delete mode 100644 src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs delete mode 100644 src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs delete mode 100644 src/test/run-pass/functions-closures/clone-closure.rs delete mode 100644 src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs delete mode 100644 src/test/run-pass/functions-closures/closure-expected-type/README.md delete mode 100644 src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs delete mode 100644 src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs delete mode 100644 src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs delete mode 100644 src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs delete mode 100644 src/test/run-pass/functions-closures/closure-immediate.rs delete mode 100644 src/test/run-pass/functions-closures/closure-inference.rs delete mode 100644 src/test/run-pass/functions-closures/closure-inference2.rs delete mode 100644 src/test/run-pass/functions-closures/closure-reform.rs delete mode 100644 src/test/run-pass/functions-closures/closure-returning-closure.rs delete mode 100644 src/test/run-pass/functions-closures/closure-to-fn-coercion.rs delete mode 100644 src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs delete mode 100644 src/test/run-pass/functions-closures/copy-closure.rs delete mode 100644 src/test/run-pass/functions-closures/fn-abi.rs delete mode 100644 src/test/run-pass/functions-closures/fn-bare-assign.rs delete mode 100644 src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs delete mode 100644 src/test/run-pass/functions-closures/fn-bare-item.rs delete mode 100644 src/test/run-pass/functions-closures/fn-bare-size.rs delete mode 100644 src/test/run-pass/functions-closures/fn-bare-spawn.rs delete mode 100644 src/test/run-pass/functions-closures/fn-coerce-field.rs delete mode 100644 src/test/run-pass/functions-closures/fn-item-type-cast.rs delete mode 100644 src/test/run-pass/functions-closures/fn-item-type-coerce.rs delete mode 100644 src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs delete mode 100644 src/test/run-pass/functions-closures/fn-lval.rs delete mode 100644 src/test/run-pass/functions-closures/fn-type-infer.rs delete mode 100644 src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs delete mode 100644 src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs delete mode 100644 src/test/run-pass/functions-closures/parallel-codegen-closures.rs delete mode 100644 src/test/run-pass/functions-closures/return-from-closure.rs delete mode 100644 src/test/run-pass/generator/addassign-yield.rs delete mode 100644 src/test/run-pass/generator/auxiliary/xcrate-reachable.rs delete mode 100644 src/test/run-pass/generator/auxiliary/xcrate.rs delete mode 100644 src/test/run-pass/generator/borrow-in-tail-expr.rs delete mode 100644 src/test/run-pass/generator/conditional-drop.rs delete mode 100644 src/test/run-pass/generator/control-flow.rs delete mode 100644 src/test/run-pass/generator/drop-and-replace.rs delete mode 100644 src/test/run-pass/generator/drop-env.rs delete mode 100644 src/test/run-pass/generator/issue-44197.rs delete mode 100644 src/test/run-pass/generator/issue-52398.rs delete mode 100644 src/test/run-pass/generator/issue-57084.rs delete mode 100644 src/test/run-pass/generator/issue-58888.rs delete mode 100644 src/test/run-pass/generator/iterator-count.rs delete mode 100644 src/test/run-pass/generator/live-upvar-across-yield.rs delete mode 100644 src/test/run-pass/generator/match-bindings.rs delete mode 100644 src/test/run-pass/generator/nested_generators.rs delete mode 100644 src/test/run-pass/generator/non-static-is-unpin.rs delete mode 100644 src/test/run-pass/generator/overlap-locals.rs delete mode 100644 src/test/run-pass/generator/panic-drops.rs delete mode 100644 src/test/run-pass/generator/panic-safe.rs delete mode 100644 src/test/run-pass/generator/pin-box-generator.rs delete mode 100644 src/test/run-pass/generator/reborrow-mut-upvar.rs delete mode 100644 src/test/run-pass/generator/resume-after-return.rs delete mode 100644 src/test/run-pass/generator/size-moved-locals.rs delete mode 100644 src/test/run-pass/generator/smoke.rs delete mode 100644 src/test/run-pass/generator/static-generators.rs delete mode 100644 src/test/run-pass/generator/too-live-local-in-immovable-gen.rs delete mode 100644 src/test/run-pass/generator/xcrate-reachable.rs delete mode 100644 src/test/run-pass/generator/xcrate.rs delete mode 100644 src/test/run-pass/generator/yield-in-args-rev.rs delete mode 100644 src/test/run-pass/generator/yield-in-box.rs delete mode 100644 src/test/run-pass/generator/yield-in-initializer.rs delete mode 100644 src/test/run-pass/generator/yield-subtype.rs delete mode 100644 src/test/run-pass/generics/auxiliary/default_type_params_xc.rs delete mode 100644 src/test/run-pass/generics/generic-alias-unique.rs delete mode 100644 src/test/run-pass/generics/generic-default-type-params-cross-crate.rs delete mode 100644 src/test/run-pass/generics/generic-default-type-params.rs delete mode 100644 src/test/run-pass/generics/generic-derived-type.rs delete mode 100644 src/test/run-pass/generics/generic-exterior-unique.rs delete mode 100644 src/test/run-pass/generics/generic-extern-mangle.rs delete mode 100644 src/test/run-pass/generics/generic-fn-infer.rs delete mode 100644 src/test/run-pass/generics/generic-fn-twice.rs delete mode 100644 src/test/run-pass/generics/generic-fn-unique.rs delete mode 100644 src/test/run-pass/generics/generic-fn.rs delete mode 100644 src/test/run-pass/generics/generic-ivec-leak.rs delete mode 100644 src/test/run-pass/generics/generic-newtype-struct.rs delete mode 100644 src/test/run-pass/generics/generic-object.rs delete mode 100644 src/test/run-pass/generics/generic-recursive-tag.rs delete mode 100644 src/test/run-pass/generics/generic-static-methods.rs delete mode 100644 src/test/run-pass/generics/generic-tag-corruption.rs delete mode 100644 src/test/run-pass/generics/generic-tag-local.rs delete mode 100644 src/test/run-pass/generics/generic-tag-match.rs delete mode 100644 src/test/run-pass/generics/generic-tag-values.rs delete mode 100644 src/test/run-pass/generics/generic-tag.rs delete mode 100644 src/test/run-pass/generics/generic-temporary.rs delete mode 100644 src/test/run-pass/generics/generic-tup.rs delete mode 100644 src/test/run-pass/generics/generic-type-synonym.rs delete mode 100644 src/test/run-pass/generics/generic-type.rs delete mode 100644 src/test/run-pass/generics/generic-unique.rs delete mode 100644 src/test/run-pass/global-scope.rs delete mode 100644 src/test/run-pass/guards-not-exhaustive.rs delete mode 100644 src/test/run-pass/guards.rs delete mode 100644 src/test/run-pass/hashmap-memory.rs delete mode 100644 src/test/run-pass/hello.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs delete mode 100644 src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs delete mode 100644 src/test/run-pass/html-literals.rs delete mode 100644 src/test/run-pass/if-bot.rs delete mode 100644 src/test/run-pass/if-check.rs delete mode 100644 src/test/run-pass/if-ret.rs delete mode 100644 src/test/run-pass/if-ret.stderr delete mode 100644 src/test/run-pass/ifmt.rs delete mode 100644 src/test/run-pass/ignore-all-the-things.rs delete mode 100644 src/test/run-pass/impl-for-never.rs delete mode 100644 src/test/run-pass/impl-inherent-non-conflict.rs delete mode 100644 src/test/run-pass/impl-not-adjacent-to-type.rs delete mode 100644 src/test/run-pass/impl-privacy-xc-1.rs delete mode 100644 src/test/run-pass/impl-privacy-xc-2.rs delete mode 100644 src/test/run-pass/impl-trait-in-bindings.rs delete mode 100644 src/test/run-pass/impl-trait-in-bindings.stderr delete mode 100644 src/test/run-pass/impl-trait/auxiliary/xcrate.rs delete mode 100644 src/test/run-pass/impl-trait/bounds_regression.rs delete mode 100644 src/test/run-pass/impl-trait/example-calendar.rs delete mode 100644 src/test/run-pass/impl-trait/example-st.rs delete mode 100644 src/test/run-pass/impl-trait/lifetimes.rs delete mode 100644 src/test/run-pass/impl-trait/nesting.rs delete mode 100644 src/test/run-pass/impl-trait/universal_hrtb_anon.rs delete mode 100644 src/test/run-pass/impl-trait/universal_hrtb_named.rs delete mode 100644 src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs delete mode 100644 src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs delete mode 100644 src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs delete mode 100644 src/test/run-pass/impl-trait/universal_multiple_bounds.rs delete mode 100644 src/test/run-pass/impl-trait/xcrate.rs delete mode 100644 src/test/run-pass/impl-trait/xcrate_simple.rs delete mode 100644 src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs delete mode 100644 src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs delete mode 100644 src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs delete mode 100644 src/test/run-pass/imports/import-from.rs delete mode 100644 src/test/run-pass/imports/import-glob-1.rs delete mode 100644 src/test/run-pass/imports/import-glob-crate.rs delete mode 100644 src/test/run-pass/imports/import-in-block.rs delete mode 100644 src/test/run-pass/imports/import-prefix-macro.rs delete mode 100644 src/test/run-pass/imports/import-rename.rs delete mode 100644 src/test/run-pass/imports/import-trailing-comma.rs delete mode 100644 src/test/run-pass/imports/import.rs delete mode 100644 src/test/run-pass/imports/import2.rs delete mode 100644 src/test/run-pass/imports/import3.rs delete mode 100644 src/test/run-pass/imports/import4.rs delete mode 100644 src/test/run-pass/imports/import5.rs delete mode 100644 src/test/run-pass/imports/import6.rs delete mode 100644 src/test/run-pass/imports/import7.rs delete mode 100644 src/test/run-pass/imports/import8.rs delete mode 100644 src/test/run-pass/imports/imports.rs delete mode 100644 src/test/run-pass/in-band-lifetimes.rs delete mode 100644 src/test/run-pass/inc-range-pat.rs delete mode 100644 src/test/run-pass/infer-fn-tail-expr.rs delete mode 100644 src/test/run-pass/inherit-env.rs delete mode 100644 src/test/run-pass/init-large-type.rs delete mode 100644 src/test/run-pass/init-res-into-things.rs delete mode 100644 src/test/run-pass/inlined-main.rs delete mode 100644 src/test/run-pass/inner-attrs-on-impl.rs delete mode 100644 src/test/run-pass/inner-module.rs delete mode 100644 src/test/run-pass/inner-static.rs delete mode 100644 src/test/run-pass/instantiable.rs delete mode 100644 src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-alignment.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-assume.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-atomics.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-move-val.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsic-unreachable.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsics-integer.rs delete mode 100644 src/test/run-pass/intrinsics/intrinsics-math.rs delete mode 100644 src/test/run-pass/invalid_const_promotion.rs delete mode 100644 src/test/run-pass/invoke-external-foreign.rs delete mode 100644 src/test/run-pass/irrefutable-unit.rs delete mode 100644 src/test/run-pass/issue-59020.rs delete mode 100644 src/test/run-pass/issues/.gitattributes delete mode 100644 src/test/run-pass/issues/auxiliary/cgu_test.rs delete mode 100644 src/test/run-pass/issues/auxiliary/cgu_test_a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/cgu_test_b.rs delete mode 100644 src/test/run-pass/issues/auxiliary/i8.rs delete mode 100644 src/test/run-pass/issues/auxiliary/iss.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-10028.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-10031-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11224.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11225-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11225-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11225-3.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11508.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-11529.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12612-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12612-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-12660-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13507.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13620-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13620-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13872-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13872-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-13872-3.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-14344-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-14344-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-14421.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-14422.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-15562.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-16643.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-17662.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-17718-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-18501.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-18514.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-18711.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-18913-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-18913-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-19293.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-19340-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-20389.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2170-lib.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2316-a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2316-b.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2380.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2414-a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2414-b.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2472-b.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-25185-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-25185-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2526.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-25467.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2631-a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-2723-a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-29485.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-3012-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-3136-a.rc delete mode 100644 src/test/run-pass/issues/auxiliary/issue-3136-a.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-31702-1.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-31702-2.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-34796-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-36954.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-38190.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-38226-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-38715-modern.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-38715.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-3979-traits.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-39823.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-40469.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-41053.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-41394.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-42007-s.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-4208-cc.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-4545.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-48984-aux.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-5518.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-5521.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-7178.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-7899.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-8044.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-8259.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-8401.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-9123.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-9155.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-9188.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-9906.rs delete mode 100644 src/test/run-pass/issues/auxiliary/issue-9968.rs delete mode 100644 src/test/run-pass/issues/issue-10025.rs delete mode 100644 src/test/run-pass/issues/issue-10028.rs delete mode 100644 src/test/run-pass/issues/issue-10031.rs delete mode 100644 src/test/run-pass/issues/issue-10228.rs delete mode 100644 src/test/run-pass/issues/issue-10392.rs delete mode 100644 src/test/run-pass/issues/issue-10436.rs delete mode 100644 src/test/run-pass/issues/issue-10626.rs delete mode 100644 src/test/run-pass/issues/issue-10638.rs delete mode 100644 src/test/run-pass/issues/issue-10682.rs delete mode 100644 src/test/run-pass/issues/issue-10683.rs delete mode 100644 src/test/run-pass/issues/issue-10718.rs delete mode 100644 src/test/run-pass/issues/issue-10734.rs delete mode 100644 src/test/run-pass/issues/issue-10767.rs delete mode 100644 src/test/run-pass/issues/issue-10802.rs delete mode 100644 src/test/run-pass/issues/issue-10806.rs delete mode 100644 src/test/run-pass/issues/issue-11047.rs delete mode 100644 src/test/run-pass/issues/issue-11085.rs delete mode 100644 src/test/run-pass/issues/issue-1112.rs delete mode 100644 src/test/run-pass/issues/issue-11205.rs delete mode 100644 src/test/run-pass/issues/issue-11224.rs delete mode 100644 src/test/run-pass/issues/issue-11225-1.rs delete mode 100644 src/test/run-pass/issues/issue-11225-2.rs delete mode 100644 src/test/run-pass/issues/issue-11225-3.rs delete mode 100644 src/test/run-pass/issues/issue-11267.rs delete mode 100644 src/test/run-pass/issues/issue-11382.rs delete mode 100644 src/test/run-pass/issues/issue-11508.rs delete mode 100644 src/test/run-pass/issues/issue-11529.rs delete mode 100644 src/test/run-pass/issues/issue-11552.rs delete mode 100644 src/test/run-pass/issues/issue-11577.rs delete mode 100644 src/test/run-pass/issues/issue-11677.rs delete mode 100644 src/test/run-pass/issues/issue-11709.rs delete mode 100644 src/test/run-pass/issues/issue-11820.rs delete mode 100644 src/test/run-pass/issues/issue-11940.rs delete mode 100644 src/test/run-pass/issues/issue-11958.rs delete mode 100644 src/test/run-pass/issues/issue-12033.rs delete mode 100644 src/test/run-pass/issues/issue-12133-1.rs delete mode 100644 src/test/run-pass/issues/issue-12133-2.rs delete mode 100644 src/test/run-pass/issues/issue-12133-3.rs delete mode 100644 src/test/run-pass/issues/issue-12285.rs delete mode 100644 src/test/run-pass/issues/issue-1257.rs delete mode 100644 src/test/run-pass/issues/issue-12582.rs delete mode 100644 src/test/run-pass/issues/issue-12612.rs delete mode 100644 src/test/run-pass/issues/issue-12660.rs delete mode 100644 src/test/run-pass/issues/issue-12677.rs delete mode 100644 src/test/run-pass/issues/issue-12699.rs delete mode 100644 src/test/run-pass/issues/issue-12744.rs delete mode 100644 src/test/run-pass/issues/issue-12860.rs delete mode 100644 src/test/run-pass/issues/issue-12909.rs delete mode 100644 src/test/run-pass/issues/issue-13027.rs delete mode 100644 src/test/run-pass/issues/issue-13204.rs delete mode 100644 src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs delete mode 100644 src/test/run-pass/issues/issue-13264.rs delete mode 100644 src/test/run-pass/issues/issue-13304.rs delete mode 100644 src/test/run-pass/issues/issue-13323.rs delete mode 100644 src/test/run-pass/issues/issue-13434.rs delete mode 100644 src/test/run-pass/issues/issue-13507-2.rs delete mode 100644 src/test/run-pass/issues/issue-13620.rs delete mode 100644 src/test/run-pass/issues/issue-13655.rs delete mode 100644 src/test/run-pass/issues/issue-13665.rs delete mode 100644 src/test/run-pass/issues/issue-13763.rs delete mode 100644 src/test/run-pass/issues/issue-13808.rs delete mode 100644 src/test/run-pass/issues/issue-13867.rs delete mode 100644 src/test/run-pass/issues/issue-13872.rs delete mode 100644 src/test/run-pass/issues/issue-13902.rs delete mode 100644 src/test/run-pass/issues/issue-14229.rs delete mode 100644 src/test/run-pass/issues/issue-14308.rs delete mode 100644 src/test/run-pass/issues/issue-14344.rs delete mode 100644 src/test/run-pass/issues/issue-14382.rs delete mode 100644 src/test/run-pass/issues/issue-14393.rs delete mode 100644 src/test/run-pass/issues/issue-14399.rs delete mode 100644 src/test/run-pass/issues/issue-14421.rs delete mode 100644 src/test/run-pass/issues/issue-14422.rs delete mode 100644 src/test/run-pass/issues/issue-14456.rs delete mode 100644 src/test/run-pass/issues/issue-1451.rs delete mode 100644 src/test/run-pass/issues/issue-14589.rs delete mode 100644 src/test/run-pass/issues/issue-1460.rs delete mode 100644 src/test/run-pass/issues/issue-14821.rs delete mode 100644 src/test/run-pass/issues/issue-14865.rs delete mode 100644 src/test/run-pass/issues/issue-14875.rs delete mode 100644 src/test/run-pass/issues/issue-14919.rs delete mode 100644 src/test/run-pass/issues/issue-14940.rs delete mode 100644 src/test/run-pass/issues/issue-14958.rs delete mode 100644 src/test/run-pass/issues/issue-15043.rs delete mode 100644 src/test/run-pass/issues/issue-15063.rs delete mode 100644 src/test/run-pass/issues/issue-15080.rs delete mode 100644 src/test/run-pass/issues/issue-15104.rs delete mode 100644 src/test/run-pass/issues/issue-15155.rs delete mode 100644 src/test/run-pass/issues/issue-15189.rs delete mode 100644 src/test/run-pass/issues/issue-15221.rs delete mode 100644 src/test/run-pass/issues/issue-15444.rs delete mode 100644 src/test/run-pass/issues/issue-15487.rs delete mode 100644 src/test/run-pass/issues/issue-15523-big.rs delete mode 100644 src/test/run-pass/issues/issue-15523.rs delete mode 100644 src/test/run-pass/issues/issue-15562.rs delete mode 100644 src/test/run-pass/issues/issue-15571.rs delete mode 100644 src/test/run-pass/issues/issue-15673.rs delete mode 100644 src/test/run-pass/issues/issue-15689-1.rs delete mode 100644 src/test/run-pass/issues/issue-15730.rs delete mode 100644 src/test/run-pass/issues/issue-15734.rs delete mode 100644 src/test/run-pass/issues/issue-15763.rs delete mode 100644 src/test/run-pass/issues/issue-15774.rs delete mode 100644 src/test/run-pass/issues/issue-15793.rs delete mode 100644 src/test/run-pass/issues/issue-15858.rs delete mode 100644 src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs delete mode 100644 src/test/run-pass/issues/issue-16151.rs delete mode 100644 src/test/run-pass/issues/issue-16256.rs delete mode 100644 src/test/run-pass/issues/issue-16272.rs delete mode 100644 src/test/run-pass/issues/issue-16278.rs delete mode 100644 src/test/run-pass/issues/issue-16441.rs delete mode 100644 src/test/run-pass/issues/issue-16452.rs delete mode 100644 src/test/run-pass/issues/issue-16492.rs delete mode 100644 src/test/run-pass/issues/issue-16530.rs delete mode 100644 src/test/run-pass/issues/issue-16560.rs delete mode 100644 src/test/run-pass/issues/issue-16597-empty.rs delete mode 100644 src/test/run-pass/issues/issue-16597.rs delete mode 100644 src/test/run-pass/issues/issue-1660.rs delete mode 100644 src/test/run-pass/issues/issue-16602-1.rs delete mode 100644 src/test/run-pass/issues/issue-16602-2.rs delete mode 100644 src/test/run-pass/issues/issue-16602-3.rs delete mode 100644 src/test/run-pass/issues/issue-16643.rs delete mode 100644 src/test/run-pass/issues/issue-16648.rs delete mode 100644 src/test/run-pass/issues/issue-16671.rs delete mode 100644 src/test/run-pass/issues/issue-16739.rs delete mode 100644 src/test/run-pass/issues/issue-16745.rs delete mode 100644 src/test/run-pass/issues/issue-16774.rs delete mode 100644 src/test/run-pass/issues/issue-16783.rs delete mode 100644 src/test/run-pass/issues/issue-16819.rs delete mode 100644 src/test/run-pass/issues/issue-1696.rs delete mode 100644 src/test/run-pass/issues/issue-1701.rs delete mode 100644 src/test/run-pass/issues/issue-17068.rs delete mode 100644 src/test/run-pass/issues/issue-17074.rs delete mode 100644 src/test/run-pass/issues/issue-17170.rs delete mode 100644 src/test/run-pass/issues/issue-17216.rs delete mode 100644 src/test/run-pass/issues/issue-17233.rs delete mode 100644 src/test/run-pass/issues/issue-17302.rs delete mode 100644 src/test/run-pass/issues/issue-17322.rs delete mode 100644 src/test/run-pass/issues/issue-17351.rs delete mode 100644 src/test/run-pass/issues/issue-17361.rs delete mode 100644 src/test/run-pass/issues/issue-17503.rs delete mode 100644 src/test/run-pass/issues/issue-17662.rs delete mode 100644 src/test/run-pass/issues/issue-17718-borrow-interior.rs delete mode 100644 src/test/run-pass/issues/issue-17718-parse-const.rs delete mode 100644 src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs delete mode 100644 src/test/run-pass/issues/issue-17718.rs delete mode 100644 src/test/run-pass/issues/issue-17734.rs delete mode 100644 src/test/run-pass/issues/issue-17756.rs delete mode 100644 src/test/run-pass/issues/issue-17771.rs delete mode 100644 src/test/run-pass/issues/issue-17816.rs delete mode 100644 src/test/run-pass/issues/issue-17877.rs delete mode 100644 src/test/run-pass/issues/issue-17897.rs delete mode 100644 src/test/run-pass/issues/issue-18060.rs delete mode 100644 src/test/run-pass/issues/issue-18075.rs delete mode 100644 src/test/run-pass/issues/issue-18110.rs delete mode 100644 src/test/run-pass/issues/issue-18173.rs delete mode 100644 src/test/run-pass/issues/issue-18232.rs delete mode 100644 src/test/run-pass/issues/issue-18352.rs delete mode 100644 src/test/run-pass/issues/issue-18353.rs delete mode 100644 src/test/run-pass/issues/issue-18412.rs delete mode 100644 src/test/run-pass/issues/issue-18425.rs delete mode 100644 src/test/run-pass/issues/issue-18464.rs delete mode 100644 src/test/run-pass/issues/issue-18501.rs delete mode 100644 src/test/run-pass/issues/issue-18514.rs delete mode 100644 src/test/run-pass/issues/issue-18539.rs delete mode 100644 src/test/run-pass/issues/issue-18652.rs delete mode 100644 src/test/run-pass/issues/issue-18655.rs delete mode 100644 src/test/run-pass/issues/issue-18661.rs delete mode 100644 src/test/run-pass/issues/issue-18685.rs delete mode 100644 src/test/run-pass/issues/issue-18711.rs delete mode 100644 src/test/run-pass/issues/issue-18767.rs delete mode 100644 src/test/run-pass/issues/issue-18804/auxiliary/lib.rs delete mode 100644 src/test/run-pass/issues/issue-18804/main.rs delete mode 100644 src/test/run-pass/issues/issue-18845.rs delete mode 100644 src/test/run-pass/issues/issue-18859.rs delete mode 100644 src/test/run-pass/issues/issue-18913.rs delete mode 100644 src/test/run-pass/issues/issue-18937-1.rs delete mode 100644 src/test/run-pass/issues/issue-18952.rs delete mode 100644 src/test/run-pass/issues/issue-19001.rs delete mode 100644 src/test/run-pass/issues/issue-19127.rs delete mode 100644 src/test/run-pass/issues/issue-19135.rs delete mode 100644 src/test/run-pass/issues/issue-19244.rs delete mode 100644 src/test/run-pass/issues/issue-19293.rs delete mode 100644 src/test/run-pass/issues/issue-19340-1.rs delete mode 100644 src/test/run-pass/issues/issue-19340-2.rs delete mode 100644 src/test/run-pass/issues/issue-19358.rs delete mode 100644 src/test/run-pass/issues/issue-19367.rs delete mode 100644 src/test/run-pass/issues/issue-19499.rs delete mode 100644 src/test/run-pass/issues/issue-1974.rs delete mode 100644 src/test/run-pass/issues/issue-19811-escape-unicode.rs delete mode 100644 src/test/run-pass/issues/issue-20055-box-trait.rs delete mode 100644 src/test/run-pass/issues/issue-20055-box-unsized-array.rs delete mode 100644 src/test/run-pass/issues/issue-20174.rs delete mode 100644 src/test/run-pass/issues/issue-20343.rs delete mode 100644 src/test/run-pass/issues/issue-20389.rs delete mode 100644 src/test/run-pass/issues/issue-20427.rs delete mode 100644 src/test/run-pass/issues/issue-20544.rs delete mode 100644 src/test/run-pass/issues/issue-20575.rs delete mode 100644 src/test/run-pass/issues/issue-20616.rs delete mode 100644 src/test/run-pass/issues/issue-2063.rs delete mode 100644 src/test/run-pass/issues/issue-20676.rs delete mode 100644 src/test/run-pass/issues/issue-2074.rs delete mode 100644 src/test/run-pass/issues/issue-20803.rs delete mode 100644 src/test/run-pass/issues/issue-20823.rs delete mode 100644 src/test/run-pass/issues/issue-20847.rs delete mode 100644 src/test/run-pass/issues/issue-20953.rs delete mode 100644 src/test/run-pass/issues/issue-21033.rs delete mode 100644 src/test/run-pass/issues/issue-21058.rs delete mode 100644 src/test/run-pass/issues/issue-21291.rs delete mode 100644 src/test/run-pass/issues/issue-21306.rs delete mode 100644 src/test/run-pass/issues/issue-21361.rs delete mode 100644 src/test/run-pass/issues/issue-21384.rs delete mode 100644 src/test/run-pass/issues/issue-21400.rs delete mode 100644 src/test/run-pass/issues/issue-21475.rs delete mode 100644 src/test/run-pass/issues/issue-21486.rs delete mode 100644 src/test/run-pass/issues/issue-21655.rs delete mode 100644 src/test/run-pass/issues/issue-2170-exe.rs delete mode 100644 src/test/run-pass/issues/issue-21721.rs delete mode 100644 src/test/run-pass/issues/issue-2190-1.rs delete mode 100644 src/test/run-pass/issues/issue-21909.rs delete mode 100644 src/test/run-pass/issues/issue-21922.rs delete mode 100644 src/test/run-pass/issues/issue-22008.rs delete mode 100644 src/test/run-pass/issues/issue-22036.rs delete mode 100644 src/test/run-pass/issues/issue-2214.rs delete mode 100644 src/test/run-pass/issues/issue-2216.rs delete mode 100644 src/test/run-pass/issues/issue-22258.rs delete mode 100644 src/test/run-pass/issues/issue-22346.rs delete mode 100644 src/test/run-pass/issues/issue-22403.rs delete mode 100644 src/test/run-pass/issues/issue-22426.rs delete mode 100644 src/test/run-pass/issues/issue-22463.rs delete mode 100644 src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs delete mode 100644 src/test/run-pass/issues/issue-22546.rs delete mode 100644 src/test/run-pass/issues/issue-22577.rs delete mode 100644 src/test/run-pass/issues/issue-22629.rs delete mode 100644 src/test/run-pass/issues/issue-22828.rs delete mode 100644 src/test/run-pass/issues/issue-2284.rs delete mode 100644 src/test/run-pass/issues/issue-22864-1.rs delete mode 100644 src/test/run-pass/issues/issue-22864-2.rs delete mode 100644 src/test/run-pass/issues/issue-2288.rs delete mode 100644 src/test/run-pass/issues/issue-22992-2.rs delete mode 100644 src/test/run-pass/issues/issue-22992.rs delete mode 100644 src/test/run-pass/issues/issue-23036.rs delete mode 100644 src/test/run-pass/issues/issue-2316-c.rs delete mode 100644 src/test/run-pass/issues/issue-23208.rs delete mode 100644 src/test/run-pass/issues/issue-23261.rs delete mode 100644 src/test/run-pass/issues/issue-23304-1.rs delete mode 100644 src/test/run-pass/issues/issue-23304-2.rs delete mode 100644 src/test/run-pass/issues/issue-23311.rs delete mode 100644 src/test/run-pass/issues/issue-23336.rs delete mode 100644 src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs delete mode 100644 src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs delete mode 100644 src/test/run-pass/issues/issue-23433.rs delete mode 100644 src/test/run-pass/issues/issue-23485.rs delete mode 100644 src/test/run-pass/issues/issue-23491.rs delete mode 100644 src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs delete mode 100644 src/test/run-pass/issues/issue-23649-1.rs delete mode 100644 src/test/run-pass/issues/issue-23649-2.rs delete mode 100644 src/test/run-pass/issues/issue-23699.rs delete mode 100644 src/test/run-pass/issues/issue-23781.rs delete mode 100644 src/test/run-pass/issues/issue-2380-b.rs delete mode 100644 src/test/run-pass/issues/issue-23808.rs delete mode 100644 src/test/run-pass/issues/issue-23825.rs delete mode 100644 src/test/run-pass/issues/issue-2383.rs delete mode 100644 src/test/run-pass/issues/issue-23833.rs delete mode 100644 src/test/run-pass/issues/issue-23891.rs delete mode 100644 src/test/run-pass/issues/issue-23898.rs delete mode 100644 src/test/run-pass/issues/issue-23958.rs delete mode 100644 src/test/run-pass/issues/issue-23968-const-not-overflow.rs delete mode 100644 src/test/run-pass/issues/issue-23992.rs delete mode 100644 src/test/run-pass/issues/issue-24010.rs delete mode 100644 src/test/run-pass/issues/issue-24086.rs delete mode 100644 src/test/run-pass/issues/issue-2414-c.rs delete mode 100644 src/test/run-pass/issues/issue-2428.rs delete mode 100644 src/test/run-pass/issues/issue-24308.rs delete mode 100644 src/test/run-pass/issues/issue-24313.rs delete mode 100644 src/test/run-pass/issues/issue-24353.rs delete mode 100644 src/test/run-pass/issues/issue-2445-b.rs delete mode 100644 src/test/run-pass/issues/issue-2445.rs delete mode 100644 src/test/run-pass/issues/issue-24533.rs delete mode 100644 src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs delete mode 100644 src/test/run-pass/issues/issue-24589.rs delete mode 100644 src/test/run-pass/issues/issue-2463.rs delete mode 100644 src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs delete mode 100644 src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs delete mode 100644 src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs delete mode 100644 src/test/run-pass/issues/issue-2472.rs delete mode 100644 src/test/run-pass/issues/issue-24779.rs delete mode 100644 src/test/run-pass/issues/issue-24805-dropck-itemless.rs delete mode 100644 src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs delete mode 100644 src/test/run-pass/issues/issue-24947.rs delete mode 100644 src/test/run-pass/issues/issue-24954.rs delete mode 100644 src/test/run-pass/issues/issue-25089.rs delete mode 100644 src/test/run-pass/issues/issue-25145.rs delete mode 100644 src/test/run-pass/issues/issue-25185.rs delete mode 100644 src/test/run-pass/issues/issue-2526-a.rs delete mode 100644 src/test/run-pass/issues/issue-25279.rs delete mode 100644 src/test/run-pass/issues/issue-25339.rs delete mode 100644 src/test/run-pass/issues/issue-25343.rs delete mode 100644 src/test/run-pass/issues/issue-25467.rs delete mode 100644 src/test/run-pass/issues/issue-25497.rs delete mode 100644 src/test/run-pass/issues/issue-2550.rs delete mode 100644 src/test/run-pass/issues/issue-25515.rs delete mode 100644 src/test/run-pass/issues/issue-25549-multiple-drop.rs delete mode 100644 src/test/run-pass/issues/issue-25679.rs delete mode 100644 src/test/run-pass/issues/issue-25693.rs delete mode 100644 src/test/run-pass/issues/issue-25700-1.rs delete mode 100644 src/test/run-pass/issues/issue-25700-2.rs delete mode 100644 src/test/run-pass/issues/issue-25746-bool-transmute.rs delete mode 100644 src/test/run-pass/issues/issue-25757.rs delete mode 100644 src/test/run-pass/issues/issue-25810.rs delete mode 100644 src/test/run-pass/issues/issue-25916.rs delete mode 100644 src/test/run-pass/issues/issue-26127.rs delete mode 100644 src/test/run-pass/issues/issue-26251.rs delete mode 100644 src/test/run-pass/issues/issue-2631-b.rs delete mode 100644 src/test/run-pass/issues/issue-26322.rs delete mode 100644 src/test/run-pass/issues/issue-2633-2.rs delete mode 100644 src/test/run-pass/issues/issue-2633.rs delete mode 100644 src/test/run-pass/issues/issue-2642.rs delete mode 100644 src/test/run-pass/issues/issue-26468.rs delete mode 100644 src/test/run-pass/issues/issue-26484.rs delete mode 100644 src/test/run-pass/issues/issue-26641.rs delete mode 100644 src/test/run-pass/issues/issue-26655.rs delete mode 100644 src/test/run-pass/issues/issue-26709.rs delete mode 100644 src/test/run-pass/issues/issue-26802.rs delete mode 100644 src/test/run-pass/issues/issue-26805.rs delete mode 100644 src/test/run-pass/issues/issue-26873-multifile.rs delete mode 100644 src/test/run-pass/issues/issue-26873-multifile/A/B.rs delete mode 100644 src/test/run-pass/issues/issue-26873-multifile/A/C.rs delete mode 100644 src/test/run-pass/issues/issue-26873-multifile/A/mod.rs delete mode 100644 src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir delete mode 100644 src/test/run-pass/issues/issue-26873-multifile/mod.rs delete mode 100644 src/test/run-pass/issues/issue-26873-onefile.rs delete mode 100644 src/test/run-pass/issues/issue-26996.rs delete mode 100644 src/test/run-pass/issues/issue-27021.rs delete mode 100644 src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs delete mode 100644 src/test/run-pass/issues/issue-2708.rs delete mode 100644 src/test/run-pass/issues/issue-2718.rs delete mode 100644 src/test/run-pass/issues/issue-2723-b.rs delete mode 100644 src/test/run-pass/issues/issue-27240.rs delete mode 100644 src/test/run-pass/issues/issue-27268.rs delete mode 100644 src/test/run-pass/issues/issue-27320.rs delete mode 100644 src/test/run-pass/issues/issue-2734.rs delete mode 100644 src/test/run-pass/issues/issue-2735-2.rs delete mode 100644 src/test/run-pass/issues/issue-2735-3.rs delete mode 100644 src/test/run-pass/issues/issue-2735.rs delete mode 100644 src/test/run-pass/issues/issue-27401-dropflag-reinit.rs delete mode 100644 src/test/run-pass/issues/issue-2748-b.rs delete mode 100644 src/test/run-pass/issues/issue-27639.rs delete mode 100644 src/test/run-pass/issues/issue-27859.rs delete mode 100644 src/test/run-pass/issues/issue-27890.rs delete mode 100644 src/test/run-pass/issues/issue-27901.rs delete mode 100644 src/test/run-pass/issues/issue-27949.rs delete mode 100644 src/test/run-pass/issues/issue-27997.rs delete mode 100644 src/test/run-pass/issues/issue-28181.rs delete mode 100644 src/test/run-pass/issues/issue-28498-must-work-ex1.rs delete mode 100644 src/test/run-pass/issues/issue-28498-must-work-ex2.rs delete mode 100644 src/test/run-pass/issues/issue-28498-ugeh-ex1.rs delete mode 100644 src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs delete mode 100644 src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs delete mode 100644 src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs delete mode 100644 src/test/run-pass/issues/issue-28550.rs delete mode 100644 src/test/run-pass/issues/issue-28676.rs delete mode 100644 src/test/run-pass/issues/issue-28777.rs delete mode 100644 src/test/run-pass/issues/issue-28828.rs delete mode 100644 src/test/run-pass/issues/issue-28839.rs delete mode 100644 src/test/run-pass/issues/issue-2895.rs delete mode 100644 src/test/run-pass/issues/issue-28950.rs delete mode 100644 src/test/run-pass/issues/issue-28983.rs delete mode 100644 src/test/run-pass/issues/issue-29053.rs delete mode 100644 src/test/run-pass/issues/issue-29071-2.rs delete mode 100644 src/test/run-pass/issues/issue-29092.rs delete mode 100644 src/test/run-pass/issues/issue-29166.rs delete mode 100644 src/test/run-pass/issues/issue-29227.rs delete mode 100644 src/test/run-pass/issues/issue-2935.rs delete mode 100644 src/test/run-pass/issues/issue-2936.rs delete mode 100644 src/test/run-pass/issues/issue-29466.rs delete mode 100644 src/test/run-pass/issues/issue-29485.rs delete mode 100644 src/test/run-pass/issues/issue-29488.rs delete mode 100644 src/test/run-pass/issues/issue-29522.rs delete mode 100644 src/test/run-pass/issues/issue-29663.rs delete mode 100644 src/test/run-pass/issues/issue-29668.rs delete mode 100644 src/test/run-pass/issues/issue-29746.rs delete mode 100644 src/test/run-pass/issues/issue-29844.rs delete mode 100644 src/test/run-pass/issues/issue-2989.rs delete mode 100644 src/test/run-pass/issues/issue-29914-2.rs delete mode 100644 src/test/run-pass/issues/issue-29914-3.rs delete mode 100644 src/test/run-pass/issues/issue-29914.rs delete mode 100644 src/test/run-pass/issues/issue-29927-1.rs delete mode 100644 src/test/run-pass/issues/issue-29927.rs delete mode 100644 src/test/run-pass/issues/issue-29948.rs delete mode 100644 src/test/run-pass/issues/issue-30018-nopanic.rs delete mode 100644 src/test/run-pass/issues/issue-30018-panic.rs delete mode 100644 src/test/run-pass/issues/issue-30081.rs delete mode 100644 src/test/run-pass/issues/issue-3012-2.rs delete mode 100644 src/test/run-pass/issues/issue-3026.rs delete mode 100644 src/test/run-pass/issues/issue-3037.rs delete mode 100644 src/test/run-pass/issues/issue-30371.rs delete mode 100644 src/test/run-pass/issues/issue-30490.rs delete mode 100644 src/test/run-pass/issues/issue-3052.rs delete mode 100644 src/test/run-pass/issues/issue-30530.rs delete mode 100644 src/test/run-pass/issues/issue-30615.rs delete mode 100644 src/test/run-pass/issues/issue-30756.rs delete mode 100644 src/test/run-pass/issues/issue-30891.rs delete mode 100644 src/test/run-pass/issues/issue-3091.rs delete mode 100644 src/test/run-pass/issues/issue-3109.rs delete mode 100644 src/test/run-pass/issues/issue-3121.rs delete mode 100644 src/test/run-pass/issues/issue-31267-additional.rs delete mode 100644 src/test/run-pass/issues/issue-31267.rs delete mode 100644 src/test/run-pass/issues/issue-31299.rs delete mode 100644 src/test/run-pass/issues/issue-3136-b.rs delete mode 100644 src/test/run-pass/issues/issue-31702.rs delete mode 100644 src/test/run-pass/issues/issue-31776.rs delete mode 100644 src/test/run-pass/issues/issue-32008.rs delete mode 100644 src/test/run-pass/issues/issue-3211.rs delete mode 100644 src/test/run-pass/issues/issue-3220.rs delete mode 100644 src/test/run-pass/issues/issue-32292.rs delete mode 100644 src/test/run-pass/issues/issue-32389.rs delete mode 100644 src/test/run-pass/issues/issue-32518.rs delete mode 100644 src/test/run-pass/issues/issue-32805.rs delete mode 100644 src/test/run-pass/issues/issue-3290.rs delete mode 100644 src/test/run-pass/issues/issue-32947.rs delete mode 100644 src/test/run-pass/issues/issue-33096.rs delete mode 100644 src/test/run-pass/issues/issue-33185.rs delete mode 100644 src/test/run-pass/issues/issue-33187.rs delete mode 100644 src/test/run-pass/issues/issue-33202.rs delete mode 100644 src/test/run-pass/issues/issue-333.rs delete mode 100644 src/test/run-pass/issues/issue-33387.rs delete mode 100644 src/test/run-pass/issues/issue-33461.rs delete mode 100644 src/test/run-pass/issues/issue-33498.rs delete mode 100644 src/test/run-pass/issues/issue-33537.rs delete mode 100644 src/test/run-pass/issues/issue-33687.rs delete mode 100644 src/test/run-pass/issues/issue-33770.rs delete mode 100644 src/test/run-pass/issues/issue-3389.rs delete mode 100644 src/test/run-pass/issues/issue-33992.rs delete mode 100644 src/test/run-pass/issues/issue-34053.rs delete mode 100644 src/test/run-pass/issues/issue-34074.rs delete mode 100644 src/test/run-pass/issues/issue-3429.rs delete mode 100644 src/test/run-pass/issues/issue-34427.rs delete mode 100644 src/test/run-pass/issues/issue-3447.rs delete mode 100644 src/test/run-pass/issues/issue-34503.rs delete mode 100644 src/test/run-pass/issues/issue-34569.rs delete mode 100644 src/test/run-pass/issues/issue-34571.rs delete mode 100644 src/test/run-pass/issues/issue-34784.rs delete mode 100644 src/test/run-pass/issues/issue-34796.rs delete mode 100644 src/test/run-pass/issues/issue-34798.rs delete mode 100644 src/test/run-pass/issues/issue-34932.rs delete mode 100644 src/test/run-pass/issues/issue-3500.rs delete mode 100644 src/test/run-pass/issues/issue-35423.rs delete mode 100644 src/test/run-pass/issues/issue-3556.rs delete mode 100644 src/test/run-pass/issues/issue-3559.rs delete mode 100644 src/test/run-pass/issues/issue-35600.rs delete mode 100644 src/test/run-pass/issues/issue-3563-3.rs delete mode 100644 src/test/run-pass/issues/issue-3574.rs delete mode 100644 src/test/run-pass/issues/issue-35815.rs delete mode 100644 src/test/run-pass/issues/issue-36023.rs delete mode 100644 src/test/run-pass/issues/issue-36036-associated-type-layout.rs delete mode 100644 src/test/run-pass/issues/issue-36053.rs delete mode 100644 src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs delete mode 100644 src/test/run-pass/issues/issue-36260.rs delete mode 100644 src/test/run-pass/issues/issue-36278-prefix-nesting.rs delete mode 100644 src/test/run-pass/issues/issue-36381.rs delete mode 100644 src/test/run-pass/issues/issue-36401.rs delete mode 100644 src/test/run-pass/issues/issue-36474.rs delete mode 100644 src/test/run-pass/issues/issue-3656.rs delete mode 100644 src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs delete mode 100644 src/test/run-pass/issues/issue-36768.rs delete mode 100644 src/test/run-pass/issues/issue-36786-resolve-call.rs delete mode 100644 src/test/run-pass/issues/issue-36792.rs delete mode 100644 src/test/run-pass/issues/issue-36816.rs delete mode 100644 src/test/run-pass/issues/issue-3683.rs delete mode 100644 src/test/run-pass/issues/issue-36856.rs delete mode 100644 src/test/run-pass/issues/issue-36936.rs delete mode 100644 src/test/run-pass/issues/issue-36954.rs delete mode 100644 src/test/run-pass/issues/issue-3702.rs delete mode 100644 src/test/run-pass/issues/issue-37109.rs delete mode 100644 src/test/run-pass/issues/issue-37175.rs delete mode 100644 src/test/run-pass/issues/issue-37222.rs delete mode 100644 src/test/run-pass/issues/issue-37291/auxiliary/lib.rs delete mode 100644 src/test/run-pass/issues/issue-37291/main.rs delete mode 100644 src/test/run-pass/issues/issue-3743.rs delete mode 100644 src/test/run-pass/issues/issue-3753.rs delete mode 100644 src/test/run-pass/issues/issue-37686.rs delete mode 100644 src/test/run-pass/issues/issue-3794.rs delete mode 100644 src/test/run-pass/issues/issue-37991.rs delete mode 100644 src/test/run-pass/issues/issue-38002.rs delete mode 100644 src/test/run-pass/issues/issue-38033.rs delete mode 100644 src/test/run-pass/issues/issue-38074.rs delete mode 100644 src/test/run-pass/issues/issue-38091.rs delete mode 100644 src/test/run-pass/issues/issue-38190.rs delete mode 100644 src/test/run-pass/issues/issue-38226.rs delete mode 100644 src/test/run-pass/issues/issue-38437.rs delete mode 100644 src/test/run-pass/issues/issue-3847.rs delete mode 100644 src/test/run-pass/issues/issue-38556.rs delete mode 100644 src/test/run-pass/issues/issue-38763.rs delete mode 100644 src/test/run-pass/issues/issue-3878.rs delete mode 100644 src/test/run-pass/issues/issue-38942.rs delete mode 100644 src/test/run-pass/issues/issue-3895.rs delete mode 100644 src/test/run-pass/issues/issue-38987.rs delete mode 100644 src/test/run-pass/issues/issue-3904.rs delete mode 100644 src/test/run-pass/issues/issue-39292.rs delete mode 100644 src/test/run-pass/issues/issue-3935.rs delete mode 100644 src/test/run-pass/issues/issue-39367.rs delete mode 100644 src/test/run-pass/issues/issue-39548.rs delete mode 100644 src/test/run-pass/issues/issue-39709.rs delete mode 100644 src/test/run-pass/issues/issue-39720.rs delete mode 100644 src/test/run-pass/issues/issue-39720.stderr delete mode 100644 src/test/run-pass/issues/issue-3979-generics.rs delete mode 100644 src/test/run-pass/issues/issue-3979-xcrate.rs delete mode 100644 src/test/run-pass/issues/issue-3979.rs delete mode 100644 src/test/run-pass/issues/issue-39808.rs delete mode 100644 src/test/run-pass/issues/issue-39823.rs delete mode 100644 src/test/run-pass/issues/issue-39827.rs delete mode 100644 src/test/run-pass/issues/issue-40003.rs delete mode 100644 src/test/run-pass/issues/issue-40085.rs delete mode 100644 src/test/run-pass/issues/issue-40235.rs delete mode 100644 src/test/run-pass/issues/issue-40408.rs delete mode 100644 src/test/run-pass/issues/issue-40469.rs delete mode 100644 src/test/run-pass/issues/issue-40770.rs delete mode 100644 src/test/run-pass/issues/issue-40847.rs delete mode 100644 src/test/run-pass/issues/issue-40883.rs delete mode 100644 src/test/run-pass/issues/issue-40951.rs delete mode 100644 src/test/run-pass/issues/issue-41053.rs delete mode 100644 src/test/run-pass/issues/issue-4107.rs delete mode 100644 src/test/run-pass/issues/issue-41213.rs delete mode 100644 src/test/run-pass/issues/issue-41479.rs delete mode 100644 src/test/run-pass/issues/issue-41498.rs delete mode 100644 src/test/run-pass/issues/issue-41604.rs delete mode 100644 src/test/run-pass/issues/issue-41677.rs delete mode 100644 src/test/run-pass/issues/issue-41696.rs delete mode 100644 src/test/run-pass/issues/issue-41744.rs delete mode 100644 src/test/run-pass/issues/issue-41803.rs delete mode 100644 src/test/run-pass/issues/issue-41849-variance-req.rs delete mode 100644 src/test/run-pass/issues/issue-41888.rs delete mode 100644 src/test/run-pass/issues/issue-42007.rs delete mode 100644 src/test/run-pass/issues/issue-4208.rs delete mode 100644 src/test/run-pass/issues/issue-42148.rs delete mode 100644 src/test/run-pass/issues/issue-42210.rs delete mode 100644 src/test/run-pass/issues/issue-4228.rs delete mode 100644 src/test/run-pass/issues/issue-42453.rs delete mode 100644 src/test/run-pass/issues/issue-42463.rs delete mode 100644 src/test/run-pass/issues/issue-4252.rs delete mode 100644 src/test/run-pass/issues/issue-42552.rs delete mode 100644 src/test/run-pass/issues/issue-42679.rs delete mode 100644 src/test/run-pass/issues/issue-42747.rs delete mode 100644 src/test/run-pass/issues/issue-43132.rs delete mode 100644 src/test/run-pass/issues/issue-43205.rs delete mode 100644 src/test/run-pass/issues/issue-43291.rs delete mode 100644 src/test/run-pass/issues/issue-4333.rs delete mode 100644 src/test/run-pass/issues/issue-43692.rs delete mode 100644 src/test/run-pass/issues/issue-43853.rs delete mode 100644 src/test/run-pass/issues/issue-4387.rs delete mode 100644 src/test/run-pass/issues/issue-43910.rs delete mode 100644 src/test/run-pass/issues/issue-43923.rs delete mode 100644 src/test/run-pass/issues/issue-4401.rs delete mode 100644 src/test/run-pass/issues/issue-44333.rs delete mode 100644 src/test/run-pass/issues/issue-4446.rs delete mode 100644 src/test/run-pass/issues/issue-4448.rs delete mode 100644 src/test/run-pass/issues/issue-45124.rs delete mode 100644 src/test/run-pass/issues/issue-45152.rs delete mode 100644 src/test/run-pass/issues/issue-4541.rs delete mode 100644 src/test/run-pass/issues/issue-4542.rs delete mode 100644 src/test/run-pass/issues/issue-4545.rs delete mode 100644 src/test/run-pass/issues/issue-45510.rs delete mode 100644 src/test/run-pass/issues/issue-45731.rs delete mode 100644 src/test/run-pass/issues/issue-46069.rs delete mode 100644 src/test/run-pass/issues/issue-46095.rs delete mode 100644 src/test/run-pass/issues/issue-46519.rs delete mode 100644 src/test/run-pass/issues/issue-46553.rs delete mode 100644 src/test/run-pass/issues/issue-46845.rs delete mode 100644 src/test/run-pass/issues/issue-46855.rs delete mode 100644 src/test/run-pass/issues/issue-46920-byte-array-patterns.rs delete mode 100644 src/test/run-pass/issues/issue-47139-1.rs delete mode 100644 src/test/run-pass/issues/issue-47139-2.rs delete mode 100644 src/test/run-pass/issues/issue-4734.rs delete mode 100644 src/test/run-pass/issues/issue-4735.rs delete mode 100644 src/test/run-pass/issues/issue-47364.rs delete mode 100644 src/test/run-pass/issues/issue-4759-1.rs delete mode 100644 src/test/run-pass/issues/issue-4759.rs delete mode 100644 src/test/run-pass/issues/issue-47638.rs delete mode 100644 src/test/run-pass/issues/issue-48006.rs delete mode 100644 src/test/run-pass/issues/issue-48159.rs delete mode 100644 src/test/run-pass/issues/issue-48508-aux.rs delete mode 100644 src/test/run-pass/issues/issue-48508.rs delete mode 100644 src/test/run-pass/issues/issue-4865-1.rs delete mode 100644 src/test/run-pass/issues/issue-4865-2.rs delete mode 100644 src/test/run-pass/issues/issue-4865-3.rs delete mode 100644 src/test/run-pass/issues/issue-4875.rs delete mode 100644 src/test/run-pass/issues/issue-48962.rs delete mode 100644 src/test/run-pass/issues/issue-48984.rs delete mode 100644 src/test/run-pass/issues/issue-49298.rs delete mode 100644 src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs delete mode 100644 src/test/run-pass/issues/issue-49632.rs delete mode 100644 src/test/run-pass/issues/issue-49685.rs delete mode 100644 src/test/run-pass/issues/issue-49854.rs delete mode 100644 src/test/run-pass/issues/issue-49955-2.rs delete mode 100644 src/test/run-pass/issues/issue-49955.rs delete mode 100644 src/test/run-pass/issues/issue-49973.rs delete mode 100644 src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs delete mode 100644 src/test/run-pass/issues/issue-50415.rs delete mode 100644 src/test/run-pass/issues/issue-50442.rs delete mode 100644 src/test/run-pass/issues/issue-5060.rs delete mode 100644 src/test/run-pass/issues/issue-50689.rs delete mode 100644 src/test/run-pass/issues/issue-50731.rs delete mode 100644 src/test/run-pass/issues/issue-50811.rs delete mode 100644 src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs delete mode 100644 src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs delete mode 100644 src/test/run-pass/issues/issue-51185.rs delete mode 100644 src/test/run-pass/issues/issue-51345.rs delete mode 100644 src/test/run-pass/issues/issue-51582.rs delete mode 100644 src/test/run-pass/issues/issue-51907.rs delete mode 100644 src/test/run-pass/issues/issue-5192.rs delete mode 100644 src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs delete mode 100644 src/test/run-pass/issues/issue-52140/main.rs delete mode 100644 src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs delete mode 100644 src/test/run-pass/issues/issue-52141/main.rs delete mode 100644 src/test/run-pass/issues/issue-52169.rs delete mode 100644 src/test/run-pass/issues/issue-5239-2.rs delete mode 100644 src/test/run-pass/issues/issue-5243.rs delete mode 100644 src/test/run-pass/issues/issue-52557.rs delete mode 100644 src/test/run-pass/issues/issue-52705/auxiliary/png2.rs delete mode 100644 src/test/run-pass/issues/issue-52705/main.rs delete mode 100644 src/test/run-pass/issues/issue-5280.rs delete mode 100644 src/test/run-pass/issues/issue-5315.rs delete mode 100644 src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs delete mode 100644 src/test/run-pass/issues/issue-53333.rs delete mode 100644 src/test/run-pass/issues/issue-53728.rs delete mode 100644 src/test/run-pass/issues/issue-53843.rs delete mode 100644 src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs delete mode 100644 src/test/run-pass/issues/issue-54467.rs delete mode 100644 src/test/run-pass/issues/issue-54477-reduced-2.rs delete mode 100644 src/test/run-pass/issues/issue-54696.rs delete mode 100644 src/test/run-pass/issues/issue-5518.rs delete mode 100644 src/test/run-pass/issues/issue-5521.rs delete mode 100644 src/test/run-pass/issues/issue-5530.rs delete mode 100644 src/test/run-pass/issues/issue-55376.rs delete mode 100644 src/test/run-pass/issues/issue-55380.rs delete mode 100644 src/test/run-pass/issues/issue-5550.rs delete mode 100644 src/test/run-pass/issues/issue-5554.rs delete mode 100644 src/test/run-pass/issues/issue-56237.rs delete mode 100644 src/test/run-pass/issues/issue-5666.rs delete mode 100644 src/test/run-pass/issues/issue-5688.rs delete mode 100644 src/test/run-pass/issues/issue-5708.rs delete mode 100644 src/test/run-pass/issues/issue-5718.rs delete mode 100644 src/test/run-pass/issues/issue-5741.rs delete mode 100644 src/test/run-pass/issues/issue-5791.rs delete mode 100644 src/test/run-pass/issues/issue-58212.rs delete mode 100644 src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs delete mode 100644 src/test/run-pass/issues/issue-58463.rs delete mode 100644 src/test/run-pass/issues/issue-5917.rs delete mode 100644 src/test/run-pass/issues/issue-5988.rs delete mode 100644 src/test/run-pass/issues/issue-5997.rs delete mode 100644 src/test/run-pass/issues/issue-6117.rs delete mode 100644 src/test/run-pass/issues/issue-6128.rs delete mode 100644 src/test/run-pass/issues/issue-6130.rs delete mode 100644 src/test/run-pass/issues/issue-6153.rs delete mode 100644 src/test/run-pass/issues/issue-6157.rs delete mode 100644 src/test/run-pass/issues/issue-61696.rs delete mode 100644 src/test/run-pass/issues/issue-61894.rs delete mode 100644 src/test/run-pass/issues/issue-6318.rs delete mode 100644 src/test/run-pass/issues/issue-6334.rs delete mode 100644 src/test/run-pass/issues/issue-6344-let.rs delete mode 100644 src/test/run-pass/issues/issue-6344-match.rs delete mode 100644 src/test/run-pass/issues/issue-6449.rs delete mode 100644 src/test/run-pass/issues/issue-6892.rs delete mode 100644 src/test/run-pass/issues/issue-6919.rs delete mode 100644 src/test/run-pass/issues/issue-7012.rs delete mode 100644 src/test/run-pass/issues/issue-7178.rs delete mode 100644 src/test/run-pass/issues/issue-7222.rs delete mode 100644 src/test/run-pass/issues/issue-7344.rs delete mode 100644 src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs delete mode 100644 src/test/run-pass/issues/issue-7563.rs delete mode 100644 src/test/run-pass/issues/issue-7575.rs delete mode 100644 src/test/run-pass/issues/issue-7660.rs delete mode 100644 src/test/run-pass/issues/issue-7663.rs delete mode 100644 src/test/run-pass/issues/issue-7784.rs delete mode 100644 src/test/run-pass/issues/issue-7899.rs delete mode 100644 src/test/run-pass/issues/issue-7911.rs delete mode 100644 src/test/run-pass/issues/issue-8044.rs delete mode 100644 src/test/run-pass/issues/issue-8248.rs delete mode 100644 src/test/run-pass/issues/issue-8249.rs delete mode 100644 src/test/run-pass/issues/issue-8259.rs delete mode 100644 src/test/run-pass/issues/issue-8351-1.rs delete mode 100644 src/test/run-pass/issues/issue-8351-2.rs delete mode 100644 src/test/run-pass/issues/issue-8391.rs delete mode 100644 src/test/run-pass/issues/issue-8401.rs delete mode 100644 src/test/run-pass/issues/issue-8460.rs delete mode 100644 src/test/run-pass/issues/issue-8498.rs delete mode 100644 src/test/run-pass/issues/issue-8506.rs delete mode 100644 src/test/run-pass/issues/issue-868.rs delete mode 100644 src/test/run-pass/issues/issue-8709.rs delete mode 100644 src/test/run-pass/issues/issue-8783.rs delete mode 100644 src/test/run-pass/issues/issue-8827.rs delete mode 100644 src/test/run-pass/issues/issue-8851.rs delete mode 100644 src/test/run-pass/issues/issue-8860.rs delete mode 100644 src/test/run-pass/issues/issue-8898.rs delete mode 100644 src/test/run-pass/issues/issue-9047.rs delete mode 100644 src/test/run-pass/issues/issue-9123.rs delete mode 100644 src/test/run-pass/issues/issue-9129.rs delete mode 100644 src/test/run-pass/issues/issue-9155.rs delete mode 100644 src/test/run-pass/issues/issue-9188.rs delete mode 100644 src/test/run-pass/issues/issue-9259.rs delete mode 100644 src/test/run-pass/issues/issue-9382.rs delete mode 100644 src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs delete mode 100644 src/test/run-pass/issues/issue-9396.rs delete mode 100644 src/test/run-pass/issues/issue-9446.rs delete mode 100644 src/test/run-pass/issues/issue-9737.rs delete mode 100644 src/test/run-pass/issues/issue-979.rs delete mode 100644 src/test/run-pass/issues/issue-9837.rs delete mode 100644 src/test/run-pass/issues/issue-9906.rs delete mode 100644 src/test/run-pass/issues/issue-9918.rs delete mode 100644 src/test/run-pass/issues/issue-9942.rs delete mode 100644 src/test/run-pass/issues/issue-9951.rs delete mode 100644 src/test/run-pass/issues/issue-9968.rs delete mode 100644 src/test/run-pass/istr.rs delete mode 100644 src/test/run-pass/item-name-overload.rs delete mode 100644 src/test/run-pass/iterators/into-iterator-type-inference-shift.rs delete mode 100644 src/test/run-pass/iterators/iter-cloned-type-inference.rs delete mode 100644 src/test/run-pass/iterators/iter-range.rs delete mode 100644 src/test/run-pass/iterators/iter-step-overflow-debug.rs delete mode 100644 src/test/run-pass/iterators/iter-step-overflow-ndebug.rs delete mode 100644 src/test/run-pass/iterators/iter-sum-overflow-debug.rs delete mode 100644 src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs delete mode 100644 src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs delete mode 100644 src/test/run-pass/iterators/iter-zip.rs delete mode 100644 src/test/run-pass/keyword-changes-2012-07-31.rs delete mode 100644 src/test/run-pass/kindck-implicit-close-over-mut-var.rs delete mode 100644 src/test/run-pass/kinds-in-metadata.rs delete mode 100644 src/test/run-pass/lambda-infer-unresolved.rs delete mode 100644 src/test/run-pass/lambda-var-hygiene.rs delete mode 100644 src/test/run-pass/large-records.rs delete mode 100644 src/test/run-pass/last-use-in-block.rs delete mode 100644 src/test/run-pass/last-use-in-cap-clause.rs delete mode 100644 src/test/run-pass/last-use-is-capture.rs delete mode 100644 src/test/run-pass/lazy-and-or.rs delete mode 100644 src/test/run-pass/lazy-init.rs delete mode 100644 src/test/run-pass/leak-unique-as-tydesc.rs delete mode 100644 src/test/run-pass/lex-bare-cr-nondoc-comment.rs delete mode 100644 src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs delete mode 100644 src/test/run-pass/lexical-scoping.rs delete mode 100644 src/test/run-pass/lib-defaults.rs delete mode 100644 src/test/run-pass/link-cfg-works.rs delete mode 100644 src/test/run-pass/link-section.rs delete mode 100644 src/test/run-pass/linkage1.rs delete mode 100644 src/test/run-pass/lint-cap.rs delete mode 100644 src/test/run-pass/lint-dead-code-associated-type.rs delete mode 100644 src/test/run-pass/lint-dead-code-variant.rs delete mode 100644 src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs delete mode 100644 src/test/run-pass/lint-unknown-lints-at-crate-level.rs delete mode 100644 src/test/run-pass/list.rs delete mode 100644 src/test/run-pass/liveness-assign-imm-local-after-ret.rs delete mode 100644 src/test/run-pass/llvm-pr32379.rs delete mode 100644 src/test/run-pass/log-err-phi.rs delete mode 100644 src/test/run-pass/log-knows-the-names-of-variants-in-std.rs delete mode 100644 src/test/run-pass/log-knows-the-names-of-variants.rs delete mode 100644 src/test/run-pass/log-poly.rs delete mode 100644 src/test/run-pass/logging-only-prints-once.rs delete mode 100644 src/test/run-pass/logging_before_rt_started.rs delete mode 100644 src/test/run-pass/long-while.rs delete mode 100644 src/test/run-pass/lto-many-codegen-units.rs delete mode 100644 src/test/run-pass/lto-still-runs-thread-dtors.rs delete mode 100644 src/test/run-pass/lub-glb-with-unbound-infer-var.rs delete mode 100644 src/test/run-pass/macro-quote-cond.rs delete mode 100644 src/test/run-pass/macro-quote-test.rs delete mode 100644 src/test/run-pass/macros/assert-eq-macro-success.rs delete mode 100644 src/test/run-pass/macros/assert-eq-macro-unsized.rs delete mode 100644 src/test/run-pass/macros/assert-ne-macro-success.rs delete mode 100644 src/test/run-pass/macros/assert-ne-macro-unsized.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro-comma-support.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro-include-items-item.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs delete mode 100644 src/test/run-pass/macros/auxiliary/macro_with_super_1.rs delete mode 100644 src/test/run-pass/macros/auxiliary/two_macros.rs delete mode 100644 src/test/run-pass/macros/auxiliary/use-macro-self.rs delete mode 100644 src/test/run-pass/macros/colorful-write-macros.rs delete mode 100644 src/test/run-pass/macros/conditional-debug-macro-on.rs delete mode 100644 src/test/run-pass/macros/die-macro.rs delete mode 100644 src/test/run-pass/macros/issue-25274.rs delete mode 100644 src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs delete mode 100644 src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout delete mode 100644 src/test/run-pass/macros/macro-2.rs delete mode 100644 src/test/run-pass/macros/macro-as-fn-body.rs delete mode 100644 src/test/run-pass/macros/macro-attribute-expansion.rs delete mode 100644 src/test/run-pass/macros/macro-attributes.rs delete mode 100644 src/test/run-pass/macros/macro-block-nonterminal.rs delete mode 100644 src/test/run-pass/macros/macro-crate-def-only.rs delete mode 100644 src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs delete mode 100644 src/test/run-pass/macros/macro-crate-nonterminal.rs delete mode 100644 src/test/run-pass/macros/macro-crate-use.rs delete mode 100644 src/test/run-pass/macros/macro-deep_expansion.rs delete mode 100644 src/test/run-pass/macros/macro-delimiter-significance.rs delete mode 100644 src/test/run-pass/macros/macro-doc-comments.rs delete mode 100644 src/test/run-pass/macros/macro-doc-escapes.rs delete mode 100644 src/test/run-pass/macros/macro-doc-raw-str-hashes.rs delete mode 100644 src/test/run-pass/macros/macro-export-inner-module.rs delete mode 100644 src/test/run-pass/macros/macro-first-set.rs delete mode 100644 src/test/run-pass/macros/macro-followed-by-seq.rs delete mode 100644 src/test/run-pass/macros/macro-include-items.rs delete mode 100644 src/test/run-pass/macros/macro-interpolation.rs delete mode 100644 src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs delete mode 100644 src/test/run-pass/macros/macro-lifetime-used-with-bound.rs delete mode 100644 src/test/run-pass/macros/macro-lifetime-used-with-labels.rs delete mode 100644 src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr delete mode 100644 src/test/run-pass/macros/macro-lifetime-used-with-static.rs delete mode 100644 src/test/run-pass/macros/macro-lifetime.rs delete mode 100644 src/test/run-pass/macros/macro-literal.rs delete mode 100644 src/test/run-pass/macros/macro-meta-items.rs delete mode 100644 src/test/run-pass/macros/macro-method-issue-4621.rs delete mode 100644 src/test/run-pass/macros/macro-multiple-items.rs delete mode 100644 src/test/run-pass/macros/macro-named-default.rs delete mode 100644 src/test/run-pass/macros/macro-nested_definition_issue-31946.rs delete mode 100644 src/test/run-pass/macros/macro-nested_expr.rs delete mode 100644 src/test/run-pass/macros/macro-nested_stmt_macros.rs delete mode 100644 src/test/run-pass/macros/macro-nt-list.rs delete mode 100644 src/test/run-pass/macros/macro-of-higher-order.rs delete mode 100644 src/test/run-pass/macros/macro-pat-follow.rs delete mode 100644 src/test/run-pass/macros/macro-pat-neg-lit.rs delete mode 100644 src/test/run-pass/macros/macro-pat.rs delete mode 100644 src/test/run-pass/macros/macro-path.rs delete mode 100644 src/test/run-pass/macros/macro-pub-matcher.rs delete mode 100644 src/test/run-pass/macros/macro-seq-followed-by-seq.rs delete mode 100644 src/test/run-pass/macros/macro-stmt.rs delete mode 100644 src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs delete mode 100644 src/test/run-pass/macros/macro-tt-followed-by-seq.rs delete mode 100644 src/test/run-pass/macros/macro-use-all-and-none.rs delete mode 100644 src/test/run-pass/macros/macro-use-all-and-none.stderr delete mode 100644 src/test/run-pass/macros/macro-use-all.rs delete mode 100644 src/test/run-pass/macros/macro-use-both.rs delete mode 100644 src/test/run-pass/macros/macro-use-one.rs delete mode 100644 src/test/run-pass/macros/macro-with-attrs1.rs delete mode 100644 src/test/run-pass/macros/macro-with-attrs2.rs delete mode 100644 src/test/run-pass/macros/macro-with-braces-in-expr-position.rs delete mode 100644 src/test/run-pass/macros/macro_with_super_2.rs delete mode 100644 src/test/run-pass/macros/meta-variable-misuse.rs delete mode 100644 src/test/run-pass/macros/parse-complex-macro-invoc-op.rs delete mode 100644 src/test/run-pass/macros/paths-in-macro-invocations.rs delete mode 100644 src/test/run-pass/macros/pub-item-inside-macro.rs delete mode 100644 src/test/run-pass/macros/pub-method-inside-macro.rs delete mode 100644 src/test/run-pass/macros/semi-after-macro-ty.rs delete mode 100644 src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs delete mode 100644 src/test/run-pass/macros/syntax-extension-cfg.rs delete mode 100644 src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment delete mode 100644 src/test/run-pass/macros/syntax-extension-source-utils.rs delete mode 100644 src/test/run-pass/macros/try-macro.rs delete mode 100644 src/test/run-pass/macros/two-macro-use.rs delete mode 100644 src/test/run-pass/macros/type-macros-hlist.rs delete mode 100644 src/test/run-pass/macros/type-macros-simple.rs delete mode 100644 src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs delete mode 100644 src/test/run-pass/macros/use-macro-self.rs delete mode 100644 src/test/run-pass/max-min-classes.rs delete mode 100644 src/test/run-pass/methods/auxiliary/method_self_arg1.rs delete mode 100644 src/test/run-pass/methods/auxiliary/method_self_arg2.rs delete mode 100644 src/test/run-pass/methods/method-argument-inference-associated-type.rs delete mode 100644 src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs delete mode 100644 src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs delete mode 100644 src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs delete mode 100644 src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs delete mode 100644 src/test/run-pass/methods/method-projection.rs delete mode 100644 src/test/run-pass/methods/method-recursive-blanket-impl.rs delete mode 100644 src/test/run-pass/methods/method-self-arg-aux1.rs delete mode 100644 src/test/run-pass/methods/method-self-arg-aux2.rs delete mode 100644 src/test/run-pass/methods/method-self-arg-trait.rs delete mode 100644 src/test/run-pass/methods/method-self-arg.rs delete mode 100644 src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs delete mode 100644 src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs delete mode 100644 src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs delete mode 100644 src/test/run-pass/methods/method-where-clause.rs delete mode 100644 src/test/run-pass/mid-path-type-params.rs delete mode 100644 src/test/run-pass/minmax-stability-issue-23687.rs delete mode 100644 src/test/run-pass/mir/auxiliary/mir_external_refs.rs delete mode 100644 src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs delete mode 100644 src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs delete mode 100644 src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs delete mode 100644 src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs delete mode 100644 src/test/run-pass/mir/mir_adt_construction.rs delete mode 100644 src/test/run-pass/mir/mir_ascription_coercion.rs delete mode 100644 src/test/run-pass/mir/mir_augmented_assignments.rs delete mode 100644 src/test/run-pass/mir/mir_autoderef.rs delete mode 100644 src/test/run-pass/mir/mir_boxing.rs delete mode 100644 src/test/run-pass/mir/mir_build_match_comparisons.rs delete mode 100644 src/test/run-pass/mir/mir_call_with_associated_type.rs delete mode 100644 src/test/run-pass/mir/mir_calls_to_shims.rs delete mode 100644 src/test/run-pass/mir/mir_cast_fn_ret.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_array.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_array_2.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_call_converging.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_calls.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_calls_variadic.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_critical_edge.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_spike1.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_switch.rs delete mode 100644 src/test/run-pass/mir/mir_codegen_switchint.rs delete mode 100644 src/test/run-pass/mir/mir_coercion_casts.rs delete mode 100644 src/test/run-pass/mir/mir_coercions.rs delete mode 100644 src/test/run-pass/mir/mir_constval_adts.rs delete mode 100644 src/test/run-pass/mir/mir_drop_order.rs delete mode 100644 src/test/run-pass/mir/mir_early_return_scope.rs delete mode 100644 src/test/run-pass/mir/mir_fat_ptr.rs delete mode 100644 src/test/run-pass/mir/mir_fat_ptr_drop.rs delete mode 100644 src/test/run-pass/mir/mir_heavy_promoted.rs delete mode 100644 src/test/run-pass/mir/mir_match_arm_guard.rs delete mode 100644 src/test/run-pass/mir/mir_match_test.rs delete mode 100644 src/test/run-pass/mir/mir_misc_casts.rs delete mode 100644 src/test/run-pass/mir/mir_overflow_off.rs delete mode 100644 src/test/run-pass/mir/mir_raw_fat_ptr.rs delete mode 100644 src/test/run-pass/mir/mir_refs_correct.rs delete mode 100644 src/test/run-pass/mir/mir_small_agg_arg.rs delete mode 100644 src/test/run-pass/mir/mir_static_subtype.rs delete mode 100644 src/test/run-pass/mir/mir_struct_with_assoc_ty.rs delete mode 100644 src/test/run-pass/mir/mir_temp_promotions.rs delete mode 100644 src/test/run-pass/mir/mir_void_return.rs delete mode 100644 src/test/run-pass/mir/mir_void_return_2.rs delete mode 100644 src/test/run-pass/modules/auxiliary/two_macros_2.rs delete mode 100644 src/test/run-pass/modules/mod-inside-fn.rs delete mode 100644 src/test/run-pass/modules/mod-view-items.rs delete mode 100644 src/test/run-pass/modules/mod_dir_implicit.rs delete mode 100644 src/test/run-pass/modules/mod_dir_implicit_aux/compiletest-ignore-dir delete mode 100644 src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs delete mode 100644 src/test/run-pass/modules/mod_dir_path.rs delete mode 100644 src/test/run-pass/modules/mod_dir_path2.rs delete mode 100644 src/test/run-pass/modules/mod_dir_path3.rs delete mode 100644 src/test/run-pass/modules/mod_dir_path_multi.rs delete mode 100644 src/test/run-pass/modules/mod_dir_recursive.rs delete mode 100644 src/test/run-pass/modules/mod_dir_simple.rs delete mode 100644 src/test/run-pass/modules/mod_dir_simple/compiletest-ignore-dir delete mode 100644 src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs delete mode 100644 src/test/run-pass/modules/mod_dir_simple/test.rs delete mode 100644 src/test/run-pass/modules/mod_file.rs delete mode 100644 src/test/run-pass/modules/mod_file_aux.rs delete mode 100644 src/test/run-pass/modules/mod_file_with_path_attr.rs delete mode 100644 src/test/run-pass/modules/module-polymorphism3-files/compiletest-ignore-dir delete mode 100644 src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs delete mode 100644 src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs delete mode 100644 src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs delete mode 100644 src/test/run-pass/monad.rs delete mode 100644 src/test/run-pass/monomorphize-abi-alignment.rs delete mode 100644 src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs delete mode 100644 src/test/run-pass/moves/move-1-unique.rs delete mode 100644 src/test/run-pass/moves/move-2-unique.rs delete mode 100644 src/test/run-pass/moves/move-2.rs delete mode 100644 src/test/run-pass/moves/move-3-unique.rs delete mode 100644 src/test/run-pass/moves/move-4-unique.rs delete mode 100644 src/test/run-pass/moves/move-4.rs delete mode 100644 src/test/run-pass/moves/move-arg-2-unique.rs delete mode 100644 src/test/run-pass/moves/move-arg-2.rs delete mode 100644 src/test/run-pass/moves/move-arg.rs delete mode 100644 src/test/run-pass/moves/move-nullary-fn.rs delete mode 100644 src/test/run-pass/moves/move-out-of-field.rs delete mode 100644 src/test/run-pass/moves/move-scalar.rs delete mode 100644 src/test/run-pass/moves/moves-based-on-type-capture-clause.rs delete mode 100644 src/test/run-pass/mpsc_stress.rs delete mode 100644 src/test/run-pass/msvc-data-only.rs delete mode 100644 src/test/run-pass/multi-panic.rs delete mode 100644 src/test/run-pass/multibyte.rs delete mode 100644 src/test/run-pass/multidispatch-conditional-impl-not-considered.rs delete mode 100644 src/test/run-pass/multidispatch1.rs delete mode 100644 src/test/run-pass/multidispatch2.rs delete mode 100644 src/test/run-pass/multiline-comment.rs delete mode 100644 src/test/run-pass/multiple-reprs.rs delete mode 100644 src/test/run-pass/mut-function-arguments.rs delete mode 100644 src/test/run-pass/mut-vstore-expr.rs delete mode 100644 src/test/run-pass/mutual-recursion-group.rs delete mode 100644 src/test/run-pass/native-print-no-runtime.rs delete mode 100644 src/test/run-pass/negative.rs delete mode 100644 src/test/run-pass/nested-block-comment.rs delete mode 100644 src/test/run-pass/nested-class.rs delete mode 100644 src/test/run-pass/nested-function-names-issue-8587.rs delete mode 100644 src/test/run-pass/nested_item_main.rs delete mode 100644 src/test/run-pass/never-result.rs delete mode 100644 src/test/run-pass/never-type-rvalues.rs delete mode 100644 src/test/run-pass/never_coercions.rs delete mode 100644 src/test/run-pass/new-box-syntax.rs delete mode 100644 src/test/run-pass/new-box.rs delete mode 100644 src/test/run-pass/new-impl-syntax.rs delete mode 100644 src/test/run-pass/new-import-syntax.rs delete mode 100644 src/test/run-pass/new-style-constants.rs delete mode 100644 src/test/run-pass/new-unicode-escapes.rs delete mode 100644 src/test/run-pass/new-unsafe-pointers.rs delete mode 100644 src/test/run-pass/newlambdas-ret-infer.rs delete mode 100644 src/test/run-pass/newlambdas-ret-infer2.rs delete mode 100644 src/test/run-pass/newlambdas.rs delete mode 100644 src/test/run-pass/newtype-polymorphic.rs delete mode 100644 src/test/run-pass/newtype-temporary.rs delete mode 100644 src/test/run-pass/newtype.rs delete mode 100644 src/test/run-pass/nil-decl-in-foreign.rs delete mode 100644 src/test/run-pass/nll/issue-47153-generic-const.rs delete mode 100644 src/test/run-pass/nll/issue-47589.rs delete mode 100644 src/test/run-pass/nll/issue-48623-closure.rs delete mode 100644 src/test/run-pass/nll/issue-48623-generator.rs delete mode 100644 src/test/run-pass/nll/issue-50343.rs delete mode 100644 src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs delete mode 100644 src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs delete mode 100644 src/test/run-pass/nll/mutating_references.rs delete mode 100644 src/test/run-pass/nll/process_or_insert_default.rs delete mode 100644 src/test/run-pass/nll/rc-loop.rs delete mode 100644 src/test/run-pass/no-core-1.rs delete mode 100644 src/test/run-pass/no-core-2.rs delete mode 100644 src/test/run-pass/no-landing-pads.rs delete mode 100644 src/test/run-pass/no-std-1.rs delete mode 100644 src/test/run-pass/no-std-2.rs delete mode 100644 src/test/run-pass/no-std-3.rs delete mode 100644 src/test/run-pass/no-stdio.rs delete mode 100644 src/test/run-pass/non-built-in-quote.rs delete mode 100644 src/test/run-pass/non-legacy-modes.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs delete mode 100644 src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs delete mode 100644 src/test/run-pass/non_modrs_mods/non_modrs_mods.rs delete mode 100644 src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs delete mode 100644 src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir delete mode 100644 src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs delete mode 100644 src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs delete mode 100644 src/test/run-pass/nul-characters.rs delete mode 100644 src/test/run-pass/nullable-pointer-ffi-compat.rs delete mode 100644 src/test/run-pass/nullable-pointer-iotareduction.rs delete mode 100644 src/test/run-pass/nullable-pointer-size.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/arith-0.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/arith-1.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/arith-2.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/arith-unsigned.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/div-mod.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float-literal-inference.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float-nan.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float-signature.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float2.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/float_math.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/floatlits.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/i128-ffi.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/i128.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/i32-sub.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/i8-incr.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/int.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/num-wrapping.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/shift-various-types.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/shift.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/u128-as-f32.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/u128.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/u32-decr.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/u8-incr.rs delete mode 100644 src/test/run-pass/numbers-arithmetic/uint.rs delete mode 100644 src/test/run-pass/object-lifetime-default-default-to-static.rs delete mode 100644 src/test/run-pass/object-lifetime-default-from-rptr-box.rs delete mode 100644 src/test/run-pass/object-lifetime-default-from-rptr-mut.rs delete mode 100644 src/test/run-pass/object-lifetime-default-from-rptr.rs delete mode 100644 src/test/run-pass/object-method-numbering.rs delete mode 100644 src/test/run-pass/objects-coerce-freeze-borrored.rs delete mode 100644 src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs delete mode 100644 src/test/run-pass/objects-owned-object-owned-method.rs delete mode 100644 src/test/run-pass/once-move-out-on-heap.rs delete mode 100644 src/test/run-pass/one-tuple.rs delete mode 100644 src/test/run-pass/op-assign-builtins-by-ref.rs delete mode 100644 src/test/run-pass/opeq.rs delete mode 100644 src/test/run-pass/operator-associativity.rs delete mode 100644 src/test/run-pass/operator-multidispatch.rs delete mode 100644 src/test/run-pass/operator-overloading.rs delete mode 100644 src/test/run-pass/optimization-fuel-0.rs delete mode 100644 src/test/run-pass/optimization-fuel-0.stderr delete mode 100644 src/test/run-pass/optimization-fuel-1.rs delete mode 100644 src/test/run-pass/optimization-fuel-1.stderr delete mode 100644 src/test/run-pass/option-ext.rs delete mode 100644 src/test/run-pass/option-unwrap.rs delete mode 100644 src/test/run-pass/out-of-stack.rs delete mode 100644 src/test/run-pass/out-pointer-aliasing.rs delete mode 100644 src/test/run-pass/output-slot-variants.rs delete mode 100644 src/test/run-pass/over-constrained-vregs.rs delete mode 100644 src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs delete mode 100644 src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs delete mode 100644 src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef-count.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef-order.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-autoderef.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-simple.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-calls-zero-args.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-deref-count.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-deref.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-index-assoc-list.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-index-autoderef.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-index-in-field.rs delete mode 100644 src/test/run-pass/overloaded/overloaded-index.rs delete mode 100644 src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs delete mode 100644 src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs delete mode 100644 src/test/run-pass/owned-implies-static.rs delete mode 100644 src/test/run-pass/packed/auxiliary/packed.rs delete mode 100644 src/test/run-pass/packed/packed-struct-borrow-element.rs delete mode 100644 src/test/run-pass/packed/packed-struct-drop-aligned.rs delete mode 100644 src/test/run-pass/packed/packed-struct-generic-layout.rs delete mode 100644 src/test/run-pass/packed/packed-struct-generic-size.rs delete mode 100644 src/test/run-pass/packed/packed-struct-layout.rs delete mode 100644 src/test/run-pass/packed/packed-struct-match.rs delete mode 100644 src/test/run-pass/packed/packed-struct-optimized-enum.rs delete mode 100644 src/test/run-pass/packed/packed-struct-size-xc.rs delete mode 100644 src/test/run-pass/packed/packed-struct-size.rs delete mode 100644 src/test/run-pass/packed/packed-struct-vec.rs delete mode 100644 src/test/run-pass/packed/packed-tuple-struct-layout.rs delete mode 100644 src/test/run-pass/packed/packed-tuple-struct-size.rs delete mode 100644 src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs delete mode 100644 src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs delete mode 100644 src/test/run-pass/panic-runtime/abort.rs delete mode 100644 src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs delete mode 100644 src/test/run-pass/panic-runtime/link-to-abort.rs delete mode 100644 src/test/run-pass/panic-runtime/link-to-unwind.rs delete mode 100644 src/test/run-pass/panic-runtime/lto-abort.rs delete mode 100644 src/test/run-pass/panic-runtime/lto-unwind.rs delete mode 100644 src/test/run-pass/panic-uninitialized-zeroed.rs delete mode 100644 src/test/run-pass/panics/panic-handler-chain.rs delete mode 100644 src/test/run-pass/panics/panic-handler-flail-wildly.rs delete mode 100644 src/test/run-pass/panics/panic-handler-set-twice.rs delete mode 100644 src/test/run-pass/panics/panic-in-dtor-drops-fields.rs delete mode 100644 src/test/run-pass/panics/panic-recover-propagate.rs delete mode 100644 src/test/run-pass/panics/panic-safe.rs delete mode 100644 src/test/run-pass/paren-free.rs delete mode 100644 src/test/run-pass/parse-assoc-type-lt.rs delete mode 100644 src/test/run-pass/parse-panic.rs delete mode 100644 src/test/run-pass/parser-unicode-whitespace.rs delete mode 100644 src/test/run-pass/path.rs delete mode 100644 src/test/run-pass/paths-containing-nul.rs delete mode 100644 src/test/run-pass/print-stdout-eprint-stderr.rs delete mode 100644 src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs delete mode 100644 src/test/run-pass/privacy/auxiliary/privacy_reexport.rs delete mode 100644 src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs delete mode 100644 src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs delete mode 100644 src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs delete mode 100644 src/test/run-pass/privacy/priv-impl-prim-ty.rs delete mode 100644 src/test/run-pass/privacy/privacy-ns.rs delete mode 100644 src/test/run-pass/privacy/privacy-reexport.rs delete mode 100644 src/test/run-pass/privacy/private-class-field.rs delete mode 100644 src/test/run-pass/privacy/pub-extern-privacy.rs delete mode 100644 src/test/run-pass/privacy/pub-use-xcrate.rs delete mode 100644 src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs delete mode 100644 src/test/run-pass/proc-macro/add-impl.rs delete mode 100644 src/test/run-pass/proc-macro/append-impl.rs delete mode 100644 src/test/run-pass/proc-macro/attr-args.rs delete mode 100644 src/test/run-pass/proc-macro/attr-cfg.rs delete mode 100644 src/test/run-pass/proc-macro/attr-on-trait.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/add-impl.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/append-impl.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/attr-args.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/bang-macro.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/call-site.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-a.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-atob.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-b.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/derive-union.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/double.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/empty-crate.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/issue-39889.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/issue-42708.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/issue-50061.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/modify-ast.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/negative-token.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/not-joint.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs delete mode 100644 src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs delete mode 100644 src/test/run-pass/proc-macro/bang-macro.rs delete mode 100644 src/test/run-pass/proc-macro/call-site.rs delete mode 100644 src/test/run-pass/proc-macro/count_compound_ops.rs delete mode 100644 src/test/run-pass/proc-macro/crate-var.rs delete mode 100644 src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs delete mode 100644 src/test/run-pass/proc-macro/derive-attr-cfg.rs delete mode 100644 src/test/run-pass/proc-macro/derive-b.rs delete mode 100644 src/test/run-pass/proc-macro/derive-same-struct.rs delete mode 100644 src/test/run-pass/proc-macro/derive-same-struct.stdout delete mode 100644 src/test/run-pass/proc-macro/derive-test.rs delete mode 100644 src/test/run-pass/proc-macro/derive-two-attrs.rs delete mode 100644 src/test/run-pass/proc-macro/derive-union.rs delete mode 100644 src/test/run-pass/proc-macro/empty-crate.rs delete mode 100644 src/test/run-pass/proc-macro/expand-with-a-macro.rs delete mode 100644 src/test/run-pass/proc-macro/gen-lifetime-token.rs delete mode 100644 src/test/run-pass/proc-macro/hygiene_example.rs delete mode 100644 src/test/run-pass/proc-macro/issue-39889.rs delete mode 100644 src/test/run-pass/proc-macro/issue-42708.rs delete mode 100644 src/test/run-pass/proc-macro/issue-50061.rs delete mode 100644 src/test/run-pass/proc-macro/load-two.rs delete mode 100644 src/test/run-pass/proc-macro/modify-ast.rs delete mode 100644 src/test/run-pass/proc-macro/negative-token.rs delete mode 100644 src/test/run-pass/proc-macro/not-joint.rs delete mode 100644 src/test/run-pass/proc-macro/smoke.rs delete mode 100644 src/test/run-pass/proc-macro/span-api-tests.rs delete mode 100644 src/test/run-pass/proc-macro/struct-field-macro.rs delete mode 100644 src/test/run-pass/proc_macro.rs delete mode 100644 src/test/run-pass/process/process-envs.rs delete mode 100644 src/test/run-pass/process/process-exit.rs delete mode 100644 src/test/run-pass/process/process-remove-from-env.rs delete mode 100644 src/test/run-pass/process/process-sigpipe.rs delete mode 100644 src/test/run-pass/process/process-spawn-nonexistent.rs delete mode 100644 src/test/run-pass/process/process-spawn-with-unicode-params.rs delete mode 100644 src/test/run-pass/process/process-status-inherits-stdin.rs delete mode 100644 src/test/run-pass/project-cache-issue-31849.rs delete mode 100644 src/test/run-pass/project-cache-issue-37154.rs delete mode 100644 src/test/run-pass/project-defer-unification.rs delete mode 100644 src/test/run-pass/pure-sum.rs delete mode 100644 src/test/run-pass/purity-infer.rs delete mode 100644 src/test/run-pass/range-type-infer.rs delete mode 100644 src/test/run-pass/range.rs delete mode 100644 src/test/run-pass/range_inclusive.rs delete mode 100644 src/test/run-pass/range_inclusive_gate.rs delete mode 100644 src/test/run-pass/ranges-precedence.rs delete mode 100644 src/test/run-pass/raw-fat-ptr.rs delete mode 100644 src/test/run-pass/raw-str.rs delete mode 100644 src/test/run-pass/rcvr-borrowed-to-region.rs delete mode 100644 src/test/run-pass/reachable-unnameable-items.rs delete mode 100644 src/test/run-pass/reachable-unnameable-type-alias.rs delete mode 100644 src/test/run-pass/readalias.rs delete mode 100644 src/test/run-pass/realloc-16687.rs delete mode 100644 src/test/run-pass/reexport-should-still-link.rs delete mode 100644 src/test/run-pass/reexport-star.rs delete mode 100644 src/test/run-pass/reexport-test-harness-main.rs delete mode 100644 src/test/run-pass/refer-to-other-statics-by-value.rs delete mode 100644 src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs delete mode 100644 src/test/run-pass/regions/regions-addr-of-ret.rs delete mode 100644 src/test/run-pass/regions/regions-assoc-type-region-bound.rs delete mode 100644 src/test/run-pass/regions/regions-assoc-type-static-bound.rs delete mode 100644 src/test/run-pass/regions/regions-borrow-at.rs delete mode 100644 src/test/run-pass/regions/regions-borrow-evec-fixed.rs delete mode 100644 src/test/run-pass/regions/regions-borrow-evec-uniq.rs delete mode 100644 src/test/run-pass/regions/regions-borrow-uniq.rs delete mode 100644 src/test/run-pass/regions/regions-bot.rs delete mode 100644 src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs delete mode 100644 src/test/run-pass/regions/regions-bound-lists-feature-gate.rs delete mode 100644 src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs delete mode 100644 src/test/run-pass/regions/regions-copy-closure.rs delete mode 100644 src/test/run-pass/regions/regions-creating-enums2.rs delete mode 100644 src/test/run-pass/regions/regions-creating-enums5.rs delete mode 100644 src/test/run-pass/regions/regions-debruijn-of-object.rs delete mode 100644 src/test/run-pass/regions/regions-dependent-addr-of.rs delete mode 100644 src/test/run-pass/regions/regions-dependent-autofn.rs delete mode 100644 src/test/run-pass/regions/regions-dependent-autoslice.rs delete mode 100644 src/test/run-pass/regions/regions-dependent-let-ref.rs delete mode 100644 src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs delete mode 100644 src/test/run-pass/regions/regions-early-bound-trait-param.rs delete mode 100644 src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs delete mode 100644 src/test/run-pass/regions/regions-early-bound-used-in-bound.rs delete mode 100644 src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs delete mode 100644 src/test/run-pass/regions/regions-escape-into-other-fn.rs delete mode 100644 src/test/run-pass/regions/regions-expl-self.rs delete mode 100644 src/test/run-pass/regions/regions-fn-subtyping-2.rs delete mode 100644 src/test/run-pass/regions/regions-fn-subtyping.rs delete mode 100644 src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs delete mode 100644 src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs delete mode 100644 src/test/run-pass/regions/regions-infer-borrow-scope-view.rs delete mode 100644 src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs delete mode 100644 src/test/run-pass/regions/regions-infer-borrow-scope.rs delete mode 100644 src/test/run-pass/regions/regions-infer-call-2.rs delete mode 100644 src/test/run-pass/regions/regions-infer-call.rs delete mode 100644 src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs delete mode 100644 src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs delete mode 100644 src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs delete mode 100644 src/test/run-pass/regions/regions-infer-static-from-proc.rs delete mode 100644 src/test/run-pass/regions/regions-issue-21422.rs delete mode 100644 src/test/run-pass/regions/regions-issue-22246.rs delete mode 100644 src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs delete mode 100644 src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs delete mode 100644 src/test/run-pass/regions/regions-link-fn-args.rs delete mode 100644 src/test/run-pass/regions/regions-lub-ref-ref-rc.rs delete mode 100644 src/test/run-pass/regions/regions-mock-codegen.rs delete mode 100644 src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs delete mode 100644 src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs delete mode 100644 src/test/run-pass/regions/regions-nullary-variant.rs delete mode 100644 src/test/run-pass/regions/regions-params.rs delete mode 100644 src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs delete mode 100644 src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs delete mode 100644 src/test/run-pass/regions/regions-refcell.rs delete mode 100644 src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs delete mode 100644 src/test/run-pass/regions/regions-return-interior-of-option.rs delete mode 100644 src/test/run-pass/regions/regions-scope-chain-example.rs delete mode 100644 src/test/run-pass/regions/regions-self-impls.rs delete mode 100644 src/test/run-pass/regions/regions-self-in-enums.rs delete mode 100644 src/test/run-pass/regions/regions-simple.rs delete mode 100644 src/test/run-pass/regions/regions-static-closure.rs delete mode 100644 src/test/run-pass/regions/regions-trait-object-1.rs delete mode 100644 src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs delete mode 100644 src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs delete mode 100644 src/test/run-pass/repeat-expr-in-static.rs delete mode 100644 src/test/run-pass/repr_c_int_align.rs delete mode 100644 src/test/run-pass/resolve-issue-2428.rs delete mode 100644 src/test/run-pass/resolve-pseudo-shadowing.rs delete mode 100644 src/test/run-pass/resource-assign-is-not-copy.rs delete mode 100644 src/test/run-pass/resource-destruct.rs delete mode 100644 src/test/run-pass/result-opt-conversions.rs delete mode 100644 src/test/run-pass/ret-bang.rs delete mode 100644 src/test/run-pass/ret-none.rs delete mode 100644 src/test/run-pass/return-nil.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1014-2.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1014.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs delete mode 100644 src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.stderr delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.stderr delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/test.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs delete mode 100644 src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs delete mode 100644 src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs delete mode 100644 src/test/run-pass/rfcs/rfc1623.rs delete mode 100644 src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs delete mode 100644 src/test/run-pass/rfcs/rfc1717/library-override.rs delete mode 100644 src/test/run-pass/rfcs/rfc1857-drop-order.rs delete mode 100644 src/test/run-pass/running-with-no-runtime.rs delete mode 100644 src/test/run-pass/rustc-rust-log.rs delete mode 100644 src/test/run-pass/rvalue-static-promotion.rs delete mode 100644 src/test/run-pass/segfault-no-out-of-stack.rs delete mode 100644 src/test/run-pass/semistatement-in-lambda.rs delete mode 100644 src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs delete mode 100644 src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs delete mode 100644 src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-cci.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-extern.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-fns.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-lib-lto.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-lib.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-statics.rs delete mode 100644 src/test/run-pass/sepcomp/sepcomp-unwind.rs delete mode 100644 src/test/run-pass/seq-compare.rs delete mode 100644 src/test/run-pass/shadow.rs delete mode 100644 src/test/run-pass/shadowed-use-visibility.rs delete mode 100644 src/test/run-pass/shebang.rs delete mode 100644 src/test/run-pass/signal-alternate-stack-cleanup.rs delete mode 100644 src/test/run-pass/signal-exit-status.rs delete mode 100644 src/test/run-pass/sigpipe-should-be-ignored.rs delete mode 100644 src/test/run-pass/simd/simd-generics.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-float-math.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-float-minmax.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-cast.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-elements.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-gather.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs delete mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-select.rs delete mode 100644 src/test/run-pass/simd/simd-size-align.rs delete mode 100644 src/test/run-pass/simd/simd-target-feature-mixup.rs delete mode 100644 src/test/run-pass/simd/simd-type.rs delete mode 100644 src/test/run-pass/simple-infer.rs delete mode 100644 src/test/run-pass/simple_global_asm.rs delete mode 100644 src/test/run-pass/size-and-align.rs delete mode 100644 src/test/run-pass/sized-borrowed-pointer.rs delete mode 100644 src/test/run-pass/sized-owned-pointer.rs delete mode 100644 src/test/run-pass/sleep.rs delete mode 100644 src/test/run-pass/slowparse-bstring.rs delete mode 100644 src/test/run-pass/slowparse-string.rs delete mode 100644 src/test/run-pass/specialization/assoc-ty-graph-cycle.rs delete mode 100644 src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs delete mode 100644 src/test/run-pass/specialization/auxiliary/go_trait.rs delete mode 100644 src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs delete mode 100644 src/test/run-pass/specialization/cross-crate-defaults.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/out-of-order.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/overlap-projection.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/projection.rs delete mode 100644 src/test/run-pass/specialization/issue-50452.rs delete mode 100644 src/test/run-pass/specialization/specialization-allowed-cross-crate.rs delete mode 100644 src/test/run-pass/specialization/specialization-assoc-fns.rs delete mode 100644 src/test/run-pass/specialization/specialization-basics.rs delete mode 100644 src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs delete mode 100644 src/test/run-pass/specialization/specialization-cross-crate.rs delete mode 100644 src/test/run-pass/specialization/specialization-default-methods.rs delete mode 100644 src/test/run-pass/specialization/specialization-on-projection.rs delete mode 100644 src/test/run-pass/specialization/specialization-out-of-order.rs delete mode 100644 src/test/run-pass/specialization/specialization-overlap-projection.rs delete mode 100644 src/test/run-pass/specialization/specialization-projection-alias.rs delete mode 100644 src/test/run-pass/specialization/specialization-projection.rs delete mode 100644 src/test/run-pass/specialization/specialization-super-traits.rs delete mode 100644 src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs delete mode 100644 src/test/run-pass/specialization/specialization-translate-projections-with-params.rs delete mode 100644 src/test/run-pass/specialization/specialization-translate-projections.rs delete mode 100644 src/test/run-pass/sse2.rs delete mode 100644 src/test/run-pass/stable-addr-of.rs delete mode 100644 src/test/run-pass/stack-probes-lto.rs delete mode 100644 src/test/run-pass/stack-probes.rs delete mode 100644 src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs delete mode 100644 src/test/run-pass/statics/auxiliary/static-methods-crate.rs delete mode 100644 src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs delete mode 100644 src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs delete mode 100644 src/test/run-pass/statics/auxiliary/static_mut_xc.rs delete mode 100644 src/test/run-pass/statics/static-fn-inline-xc.rs delete mode 100644 src/test/run-pass/statics/static-fn-trait-xc.rs delete mode 100644 src/test/run-pass/statics/static-function-pointer-xc.rs delete mode 100644 src/test/run-pass/statics/static-function-pointer.rs delete mode 100644 src/test/run-pass/statics/static-impl.rs delete mode 100644 src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs delete mode 100644 src/test/run-pass/statics/static-method-xcrate.rs delete mode 100644 src/test/run-pass/statics/static-methods-in-traits.rs delete mode 100644 src/test/run-pass/statics/static-methods-in-traits2.rs delete mode 100644 src/test/run-pass/statics/static-mut-foreign.rs delete mode 100644 src/test/run-pass/statics/static-mut-xc.rs delete mode 100644 src/test/run-pass/statics/static-recursive.rs delete mode 100644 src/test/run-pass/stdio-is-blocking.rs delete mode 100644 src/test/run-pass/str-concat.rs delete mode 100644 src/test/run-pass/str-multiline.rs delete mode 100644 src/test/run-pass/string-box-error.rs delete mode 100644 src/test/run-pass/string-escapes.rs delete mode 100644 src/test/run-pass/struct-ctor-mangling.rs delete mode 100644 src/test/run-pass/structs-enums/align-enum.rs delete mode 100644 src/test/run-pass/structs-enums/align-struct.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/empty-struct.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs delete mode 100644 src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs delete mode 100644 src/test/run-pass/structs-enums/borrow-tuple-fields.rs delete mode 100644 src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs delete mode 100644 src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs delete mode 100644 src/test/run-pass/structs-enums/class-cast-to-trait.rs delete mode 100644 src/test/run-pass/structs-enums/class-dtor.rs delete mode 100644 src/test/run-pass/structs-enums/class-exports.rs delete mode 100644 src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs delete mode 100644 src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/class-implement-traits.rs delete mode 100644 src/test/run-pass/structs-enums/class-method-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/class-methods-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/class-methods.rs delete mode 100644 src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/class-poly-methods.rs delete mode 100644 src/test/run-pass/structs-enums/class-separate-impl.rs delete mode 100644 src/test/run-pass/structs-enums/class-str-field.rs delete mode 100644 src/test/run-pass/structs-enums/class-typarams.rs delete mode 100644 src/test/run-pass/structs-enums/classes-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/classes-self-referential.rs delete mode 100644 src/test/run-pass/structs-enums/classes-simple-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/classes-simple-method.rs delete mode 100644 src/test/run-pass/structs-enums/classes-simple.rs delete mode 100644 src/test/run-pass/structs-enums/classes.rs delete mode 100644 src/test/run-pass/structs-enums/codegen-tag-static-padding.rs delete mode 100644 src/test/run-pass/structs-enums/compare-generic-enums.rs delete mode 100644 src/test/run-pass/structs-enums/discrim-explicit-23030.rs delete mode 100644 src/test/run-pass/structs-enums/empty-struct-braces.rs delete mode 100644 src/test/run-pass/structs-enums/empty-tag.rs delete mode 100644 src/test/run-pass/structs-enums/enum-alignment.rs delete mode 100644 src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs delete mode 100644 src/test/run-pass/structs-enums/enum-discr.rs delete mode 100644 src/test/run-pass/structs-enums/enum-discrim-autosizing.rs delete mode 100644 src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs delete mode 100644 src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs delete mode 100644 src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs delete mode 100644 src/test/run-pass/structs-enums/enum-disr-val-pretty.rs delete mode 100644 src/test/run-pass/structs-enums/enum-export-inheritance.rs delete mode 100644 src/test/run-pass/structs-enums/enum-layout-optimization.rs delete mode 100644 src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs delete mode 100644 src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs delete mode 100644 src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs delete mode 100644 src/test/run-pass/structs-enums/enum-null-pointer-opt.rs delete mode 100644 src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs delete mode 100644 src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs delete mode 100644 src/test/run-pass/structs-enums/enum-univariant-repr.rs delete mode 100644 src/test/run-pass/structs-enums/enum-variants.rs delete mode 100644 src/test/run-pass/structs-enums/enum-vec-initializer.rs delete mode 100644 src/test/run-pass/structs-enums/export-abstract-tag.rs delete mode 100644 src/test/run-pass/structs-enums/export-tag-variant.rs delete mode 100644 src/test/run-pass/structs-enums/expr-if-struct.rs delete mode 100644 src/test/run-pass/structs-enums/expr-match-struct.rs delete mode 100644 src/test/run-pass/structs-enums/field-destruction-order.rs delete mode 100644 src/test/run-pass/structs-enums/foreign-struct.rs delete mode 100644 src/test/run-pass/structs-enums/functional-struct-upd.rs delete mode 100644 src/test/run-pass/structs-enums/ivec-tag.rs delete mode 100644 src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs delete mode 100644 src/test/run-pass/structs-enums/namespaced-enums.rs delete mode 100644 src/test/run-pass/structs-enums/nested-enum-same-names.rs delete mode 100644 src/test/run-pass/structs-enums/newtype-struct-drop-run.rs delete mode 100644 src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs delete mode 100644 src/test/run-pass/structs-enums/newtype-struct-xc-2.rs delete mode 100644 src/test/run-pass/structs-enums/newtype-struct-xc.rs delete mode 100644 src/test/run-pass/structs-enums/nonzero-enum.rs delete mode 100644 src/test/run-pass/structs-enums/numeric-fields.rs delete mode 100644 src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs delete mode 100644 src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs delete mode 100644 src/test/run-pass/structs-enums/rec-align-u32.rs delete mode 100644 src/test/run-pass/structs-enums/rec-align-u64.rs delete mode 100644 src/test/run-pass/structs-enums/rec-auto.rs delete mode 100644 src/test/run-pass/structs-enums/rec-extend.rs delete mode 100644 src/test/run-pass/structs-enums/rec-tup.rs delete mode 100644 src/test/run-pass/structs-enums/rec.rs delete mode 100644 src/test/run-pass/structs-enums/record-pat.rs delete mode 100644 src/test/run-pass/structs-enums/resource-in-struct.rs delete mode 100644 src/test/run-pass/structs-enums/simple-generic-tag.rs delete mode 100644 src/test/run-pass/structs-enums/simple-match-generic-tag.rs delete mode 100644 src/test/run-pass/structs-enums/small-enum-range-edge.rs delete mode 100644 src/test/run-pass/structs-enums/small-enums-with-fields.rs delete mode 100644 src/test/run-pass/structs-enums/struct-aliases-xcrate.rs delete mode 100644 src/test/run-pass/structs-enums/struct-aliases.rs delete mode 100644 src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs delete mode 100644 src/test/run-pass/structs-enums/struct-field-shorthand.rs delete mode 100644 src/test/run-pass/structs-enums/struct-like-variant-construct.rs delete mode 100644 src/test/run-pass/structs-enums/struct-like-variant-match.rs delete mode 100644 src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs delete mode 100644 src/test/run-pass/structs-enums/struct-literal-dtor.rs delete mode 100644 src/test/run-pass/structs-enums/struct-new-as-field-name.rs delete mode 100644 src/test/run-pass/structs-enums/struct-order-of-eval-1.rs delete mode 100644 src/test/run-pass/structs-enums/struct-order-of-eval-2.rs delete mode 100644 src/test/run-pass/structs-enums/struct-order-of-eval-3.rs delete mode 100644 src/test/run-pass/structs-enums/struct-order-of-eval-4.rs delete mode 100644 src/test/run-pass/structs-enums/struct-partial-move-1.rs delete mode 100644 src/test/run-pass/structs-enums/struct-partial-move-2.rs delete mode 100644 src/test/run-pass/structs-enums/struct-path-associated-type.rs delete mode 100644 src/test/run-pass/structs-enums/struct-path-self.rs delete mode 100644 src/test/run-pass/structs-enums/struct-pattern-matching.rs delete mode 100644 src/test/run-pass/structs-enums/struct-return.rs delete mode 100644 src/test/run-pass/structs-enums/struct-variant-field-visibility.rs delete mode 100644 src/test/run-pass/structs-enums/struct_variant_xc.rs delete mode 100644 src/test/run-pass/structs-enums/struct_variant_xc_match.rs delete mode 100644 src/test/run-pass/structs-enums/tag-align-dyn-u64.rs delete mode 100644 src/test/run-pass/structs-enums/tag-align-dyn-variants.rs delete mode 100644 src/test/run-pass/structs-enums/tag-align-shape.rs delete mode 100644 src/test/run-pass/structs-enums/tag-align-u64.rs delete mode 100644 src/test/run-pass/structs-enums/tag-disr-val-shape.rs delete mode 100644 src/test/run-pass/structs-enums/tag-exports.rs delete mode 100644 src/test/run-pass/structs-enums/tag-in-block.rs delete mode 100644 src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs delete mode 100644 src/test/run-pass/structs-enums/tag-variant-disr-val.rs delete mode 100644 src/test/run-pass/structs-enums/tag.rs delete mode 100644 src/test/run-pass/structs-enums/tuple-struct-construct.rs delete mode 100644 src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs delete mode 100644 src/test/run-pass/structs-enums/tuple-struct-destructuring.rs delete mode 100644 src/test/run-pass/structs-enums/tuple-struct-matching.rs delete mode 100644 src/test/run-pass/structs-enums/tuple-struct-trivial.rs delete mode 100644 src/test/run-pass/structs-enums/uninstantiable-struct.rs delete mode 100644 src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs delete mode 100644 src/test/run-pass/structs-enums/unit-like-struct.rs delete mode 100644 src/test/run-pass/structs-enums/variant-structs-trivial.rs delete mode 100644 src/test/run-pass/structured-compare.rs delete mode 100644 src/test/run-pass/super-fast-paren-parsing.rs delete mode 100644 src/test/run-pass/super.rs delete mode 100644 src/test/run-pass/supported-cast.rs delete mode 100644 src/test/run-pass/svh-add-nothing.rs delete mode 100644 src/test/run-pass/swap-1.rs delete mode 100644 src/test/run-pass/swap-2.rs delete mode 100644 src/test/run-pass/swap-overlapping.rs delete mode 100644 src/test/run-pass/tail-call-arg-leak.rs delete mode 100644 src/test/run-pass/tail-cps.rs delete mode 100644 src/test/run-pass/tail-direct.rs delete mode 100644 src/test/run-pass/tcp-stress.rs delete mode 100644 src/test/run-pass/terminate-in-initializer.rs delete mode 100644 src/test/run-pass/test-allow-dead-extern-static-no-warning.rs delete mode 100644 src/test/run-pass/test-allow-fail-attr.rs delete mode 100644 src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs delete mode 100644 src/test/run-pass/test-main-not-dead-attr.rs delete mode 100644 src/test/run-pass/test-main-not-dead.rs delete mode 100644 src/test/run-pass/test-runner-hides-buried-main.rs delete mode 100644 src/test/run-pass/test-runner-hides-main.rs delete mode 100644 src/test/run-pass/test-runner-hides-start.rs delete mode 100644 src/test/run-pass/test-should-fail-good-message.rs delete mode 100644 src/test/run-pass/test-vs-cfg-test.rs delete mode 100644 src/test/run-pass/thin-lto-global-allocator.rs delete mode 100644 src/test/run-pass/thinlto/all-crates.rs delete mode 100644 src/test/run-pass/thinlto/auxiliary/dylib.rs delete mode 100644 src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs delete mode 100644 src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs delete mode 100644 src/test/run-pass/thinlto/dylib-works.rs delete mode 100644 src/test/run-pass/thinlto/msvc-imp-present.rs delete mode 100644 src/test/run-pass/thinlto/thin-lto-inlines.rs delete mode 100644 src/test/run-pass/thinlto/thin-lto-inlines2.rs delete mode 100644 src/test/run-pass/thinlto/weak-works.rs delete mode 100644 src/test/run-pass/thread-local-not-in-prelude.rs delete mode 100644 src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs delete mode 100644 src/test/run-pass/threads-sendsync/comm.rs delete mode 100644 src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs delete mode 100644 src/test/run-pass/threads-sendsync/send-resource.rs delete mode 100644 src/test/run-pass/threads-sendsync/send-type-inference.rs delete mode 100644 src/test/run-pass/threads-sendsync/send_str_hashmap.rs delete mode 100644 src/test/run-pass/threads-sendsync/send_str_treemap.rs delete mode 100644 src/test/run-pass/threads-sendsync/sendable-class.rs delete mode 100644 src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs delete mode 100644 src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs delete mode 100644 src/test/run-pass/threads-sendsync/spawn-fn.rs delete mode 100644 src/test/run-pass/threads-sendsync/spawn-types.rs delete mode 100644 src/test/run-pass/threads-sendsync/spawn.rs delete mode 100644 src/test/run-pass/threads-sendsync/spawn2.rs delete mode 100644 src/test/run-pass/threads-sendsync/spawning-with-debug.rs delete mode 100644 src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs delete mode 100644 src/test/run-pass/threads-sendsync/sync-send-atomics.rs delete mode 100644 src/test/run-pass/threads-sendsync/sync-send-in-std.rs delete mode 100644 src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs delete mode 100644 src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-0.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-1.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-10.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-11.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-12.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-13.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-14.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-15.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-16.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-17.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-3.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-4.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-5.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-6.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-7.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-9.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-life-0.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs delete mode 100644 src/test/run-pass/threads-sendsync/task-stderr.rs delete mode 100644 src/test/run-pass/threads-sendsync/thread-local-extern-static.rs delete mode 100644 src/test/run-pass/threads-sendsync/thread-local-syntax.rs delete mode 100644 src/test/run-pass/threads-sendsync/threads.rs delete mode 100644 src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs delete mode 100644 src/test/run-pass/threads-sendsync/tls-init-on-init.rs delete mode 100644 src/test/run-pass/threads-sendsync/tls-try-with.rs delete mode 100644 src/test/run-pass/tool_attributes.rs delete mode 100644 src/test/run-pass/tool_lints_2018_preview.rs delete mode 100644 src/test/run-pass/trailing-comma.rs delete mode 100644 src/test/run-pass/traits/anon-trait-static-method.rs delete mode 100644 src/test/run-pass/traits/anon_trait_static_method_exe.rs delete mode 100644 src/test/run-pass/traits/assignability-trait.rs delete mode 100644 src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs delete mode 100644 src/test/run-pass/traits/augmented-assignments-trait.rs delete mode 100644 src/test/run-pass/traits/auto-traits.rs delete mode 100644 src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs delete mode 100644 src/test/run-pass/traits/auxiliary/go_trait.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_alias.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs delete mode 100644 src/test/run-pass/traits/auxiliary/traitimpl.rs delete mode 100644 src/test/run-pass/traits/cycle-trait-type-trait.rs delete mode 100644 src/test/run-pass/traits/default-method-supertrait-vtable.rs delete mode 100644 src/test/run-pass/traits/dyn-trait.rs delete mode 100644 src/test/run-pass/traits/fmt-pointer-trait.rs delete mode 100644 src/test/run-pass/traits/impl-implicit-trait.rs delete mode 100644 src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs delete mode 100644 src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs delete mode 100644 src/test/run-pass/traits/inherent-trait-method-order.rs delete mode 100644 src/test/run-pass/traits/kindck-owned-trait-contains-1.rs delete mode 100644 src/test/run-pass/traits/multiple-trait-bounds.rs delete mode 100644 src/test/run-pass/traits/object-one-type-two-traits.rs delete mode 100644 src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs delete mode 100644 src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs delete mode 100644 src/test/run-pass/traits/parameterized-trait-with-bounds.rs delete mode 100644 src/test/run-pass/traits/principal-less-trait-objects.rs delete mode 100644 src/test/run-pass/traits/supertrait-default-generics.rs delete mode 100644 src/test/run-pass/traits/syntax-trait-polarity.rs delete mode 100644 src/test/run-pass/traits/trait-alias-import-cross-crate.rs delete mode 100644 src/test/run-pass/traits/trait-alias-import.rs delete mode 100644 src/test/run-pass/traits/trait-bounds-basic.rs delete mode 100644 src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs delete mode 100644 src/test/run-pass/traits/trait-bounds-in-arc.rs delete mode 100644 src/test/run-pass/traits/trait-bounds-recursion.rs delete mode 100644 src/test/run-pass/traits/trait-bounds.rs delete mode 100644 src/test/run-pass/traits/trait-cache-issue-18209.rs delete mode 100644 src/test/run-pass/traits/trait-coercion-generic.rs delete mode 100644 src/test/run-pass/traits/trait-coercion.rs delete mode 100644 src/test/run-pass/traits/trait-composition-trivial.rs delete mode 100644 src/test/run-pass/traits/trait-copy-guessing.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-bound-subst.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-bound-subst2.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-bound-subst3.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-bound-subst4.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-bound.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-xc-2.rs delete mode 100644 src/test/run-pass/traits/trait-default-method-xc.rs delete mode 100644 src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs delete mode 100644 src/test/run-pass/traits/trait-generic.rs delete mode 100644 src/test/run-pass/traits/trait-impl-2.rs delete mode 100644 src/test/run-pass/traits/trait-impl.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-auto-xc.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-auto.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-cast.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-diamond.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-multiple-params.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num0.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num1.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num2.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num3.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-num5.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-overloading-simple.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-overloading.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-self.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-simple.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-static.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-static2.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-subst.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-subst2.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance-visibility.rs delete mode 100644 src/test/run-pass/traits/trait-inheritance2.rs delete mode 100644 src/test/run-pass/traits/trait-item-inside-macro.rs delete mode 100644 src/test/run-pass/traits/trait-object-auto-dedup.rs delete mode 100644 src/test/run-pass/traits/trait-object-exclusion.rs delete mode 100644 src/test/run-pass/traits/trait-object-generics.rs delete mode 100644 src/test/run-pass/traits/trait-object-lifetime-first.rs delete mode 100644 src/test/run-pass/traits/trait-object-with-lifetime-bound.rs delete mode 100644 src/test/run-pass/traits/trait-region-pointer-simple.rs delete mode 100644 src/test/run-pass/traits/trait-safety-ok-cc.rs delete mode 100644 src/test/run-pass/traits/trait-safety-ok.rs delete mode 100644 src/test/run-pass/traits/trait-static-method-overwriting.rs delete mode 100644 src/test/run-pass/traits/trait-to-str.rs delete mode 100644 src/test/run-pass/traits/trait-where-clause-vs-impl.rs delete mode 100644 src/test/run-pass/traits/trait-with-bounds-default.rs delete mode 100644 src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs delete mode 100644 src/test/run-pass/traits/traits-conditional-dispatch.rs delete mode 100644 src/test/run-pass/traits/traits-conditional-model-fn.rs delete mode 100644 src/test/run-pass/traits/traits-default-method-macro.rs delete mode 100644 src/test/run-pass/traits/traits-default-method-mut.rs delete mode 100644 src/test/run-pass/traits/traits-default-method-self.rs delete mode 100644 src/test/run-pass/traits/traits-default-method-trivial.rs delete mode 100644 src/test/run-pass/traits/traits-elaborate-type-region.rs delete mode 100644 src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs delete mode 100644 src/test/run-pass/traits/traits-issue-22019.rs delete mode 100644 src/test/run-pass/traits/traits-issue-22110.rs delete mode 100644 src/test/run-pass/traits/traits-issue-22655.rs delete mode 100644 src/test/run-pass/traits/traits-issue-23003.rs delete mode 100644 src/test/run-pass/traits/traits-issue-26339.rs delete mode 100644 src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs delete mode 100644 src/test/run-pass/traits/traits-repeated-supertrait.rs delete mode 100644 src/test/run-pass/traits/ufcs-trait-object.rs delete mode 100644 src/test/run-pass/traits/use-trait-before-def.rs delete mode 100644 src/test/run-pass/transmute-non-immediate-to-immediate.rs delete mode 100644 src/test/run-pass/transmute-specialization.rs delete mode 100644 src/test/run-pass/trivial-message.rs delete mode 100644 src/test/run-pass/try-block.rs delete mode 100644 src/test/run-pass/try-from-int-error-partial-eq.rs delete mode 100644 src/test/run-pass/try-is-identifier-edition2015.rs delete mode 100644 src/test/run-pass/try-operator-custom.rs delete mode 100644 src/test/run-pass/try-operator-hygiene.rs delete mode 100644 src/test/run-pass/try-operator.rs delete mode 100644 src/test/run-pass/try-wait.rs delete mode 100644 src/test/run-pass/try_from.rs delete mode 100644 src/test/run-pass/tup.rs delete mode 100644 src/test/run-pass/tuple-index-fat-types.rs delete mode 100644 src/test/run-pass/tuple-index.rs delete mode 100644 src/test/run-pass/tydesc-name.rs delete mode 100644 src/test/run-pass/type-ascription.rs delete mode 100644 src/test/run-pass/type-id-higher-rank-2.rs delete mode 100644 src/test/run-pass/type-id-higher-rank.rs delete mode 100644 src/test/run-pass/type-in-nested-module.rs delete mode 100644 src/test/run-pass/type-infer-generalize-ty-var.rs delete mode 100644 src/test/run-pass/type-namespace.rs delete mode 100644 src/test/run-pass/type-param-constraints.rs delete mode 100644 src/test/run-pass/type-param.rs delete mode 100644 src/test/run-pass/type-params-in-for-each.rs delete mode 100644 src/test/run-pass/type-ptr.rs delete mode 100644 src/test/run-pass/type-sizes.rs delete mode 100644 src/test/run-pass/type-use-i1-versus-i8.rs delete mode 100644 src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs delete mode 100644 src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs delete mode 100644 src/test/run-pass/typeck_type_placeholder_1.rs delete mode 100644 src/test/run-pass/typeclasses-eq-example-static.rs delete mode 100644 src/test/run-pass/typeclasses-eq-example.rs delete mode 100644 src/test/run-pass/typeid-intrinsic.rs delete mode 100644 src/test/run-pass/typestate-cfg-nesting.rs delete mode 100644 src/test/run-pass/typestate-multi-decl.rs delete mode 100644 src/test/run-pass/ufcs-polymorphic-paths.rs delete mode 100644 src/test/run-pass/ufcs-type-params.rs delete mode 100644 src/test/run-pass/unary-minus-suffix-inference.rs delete mode 100644 src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs delete mode 100644 src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs delete mode 100644 src/test/run-pass/underscore-lifetimes.rs delete mode 100644 src/test/run-pass/underscore-method-after-integer.rs delete mode 100644 src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs delete mode 100644 src/test/run-pass/uniform-paths/basic-nested.rs delete mode 100644 src/test/run-pass/uniform-paths/basic.rs delete mode 100644 src/test/run-pass/uniform-paths/issue-53691.rs delete mode 100644 src/test/run-pass/uniform-paths/macros-nested.rs delete mode 100644 src/test/run-pass/uniform-paths/macros.rs delete mode 100644 src/test/run-pass/uniform-paths/same-crate.rs delete mode 100644 src/test/run-pass/unify-return-ty.rs delete mode 100644 src/test/run-pass/uninit-empty-types.rs delete mode 100644 src/test/run-pass/union/auxiliary/union.rs delete mode 100644 src/test/run-pass/union/union-align.rs delete mode 100644 src/test/run-pass/union/union-backcomp.rs delete mode 100644 src/test/run-pass/union/union-basic.rs delete mode 100644 src/test/run-pass/union/union-c-interop.rs delete mode 100644 src/test/run-pass/union/union-const-codegen.rs delete mode 100644 src/test/run-pass/union/union-const-eval-field.rs delete mode 100644 src/test/run-pass/union/union-drop-assign.rs delete mode 100644 src/test/run-pass/union/union-drop.rs delete mode 100644 src/test/run-pass/union/union-inherent-method.rs delete mode 100644 src/test/run-pass/union/union-macro.rs delete mode 100644 src/test/run-pass/union/union-nodrop.rs delete mode 100644 src/test/run-pass/union/union-nonzero.rs delete mode 100644 src/test/run-pass/union/union-overwrite.rs delete mode 100644 src/test/run-pass/union/union-packed.rs delete mode 100644 src/test/run-pass/union/union-pat-refutability.rs delete mode 100644 src/test/run-pass/union/union-trait-impl.rs delete mode 100644 src/test/run-pass/union/union-transmute.rs delete mode 100644 src/test/run-pass/unique/unique-assign-copy.rs delete mode 100644 src/test/run-pass/unique/unique-assign-drop.rs delete mode 100644 src/test/run-pass/unique/unique-assign-generic.rs delete mode 100644 src/test/run-pass/unique/unique-assign.rs delete mode 100644 src/test/run-pass/unique/unique-autoderef-field.rs delete mode 100644 src/test/run-pass/unique/unique-autoderef-index.rs delete mode 100644 src/test/run-pass/unique/unique-cmp.rs delete mode 100644 src/test/run-pass/unique/unique-containing-tag.rs delete mode 100644 src/test/run-pass/unique/unique-create.rs delete mode 100644 src/test/run-pass/unique/unique-decl-init-copy.rs delete mode 100644 src/test/run-pass/unique/unique-decl-init.rs delete mode 100644 src/test/run-pass/unique/unique-decl-move.rs delete mode 100644 src/test/run-pass/unique/unique-decl.rs delete mode 100644 src/test/run-pass/unique/unique-deref.rs delete mode 100644 src/test/run-pass/unique/unique-destructure.rs delete mode 100644 src/test/run-pass/unique/unique-drop-complex.rs delete mode 100644 src/test/run-pass/unique/unique-ffi-symbols.rs delete mode 100644 src/test/run-pass/unique/unique-fn-arg-move.rs delete mode 100644 src/test/run-pass/unique/unique-fn-arg-mut.rs delete mode 100644 src/test/run-pass/unique/unique-fn-arg.rs delete mode 100644 src/test/run-pass/unique/unique-fn-ret.rs delete mode 100644 src/test/run-pass/unique/unique-generic-assign.rs delete mode 100644 src/test/run-pass/unique/unique-in-tag.rs delete mode 100644 src/test/run-pass/unique/unique-in-vec-copy.rs delete mode 100644 src/test/run-pass/unique/unique-in-vec.rs delete mode 100644 src/test/run-pass/unique/unique-init.rs delete mode 100644 src/test/run-pass/unique/unique-kinds.rs delete mode 100644 src/test/run-pass/unique/unique-log.rs delete mode 100644 src/test/run-pass/unique/unique-match-discrim.rs delete mode 100644 src/test/run-pass/unique/unique-move-drop.rs delete mode 100644 src/test/run-pass/unique/unique-move-temp.rs delete mode 100644 src/test/run-pass/unique/unique-move.rs delete mode 100644 src/test/run-pass/unique/unique-mutable.rs delete mode 100644 src/test/run-pass/unique/unique-object-move.rs delete mode 100644 src/test/run-pass/unique/unique-pat-2.rs delete mode 100644 src/test/run-pass/unique/unique-pat-3.rs delete mode 100644 src/test/run-pass/unique/unique-pat.rs delete mode 100644 src/test/run-pass/unique/unique-rec.rs delete mode 100644 src/test/run-pass/unique/unique-send-2.rs delete mode 100644 src/test/run-pass/unique/unique-send.rs delete mode 100644 src/test/run-pass/unique/unique-swap.rs delete mode 100644 src/test/run-pass/unit.rs delete mode 100644 src/test/run-pass/unnamed_argument_mode.rs delete mode 100644 src/test/run-pass/unreachable-code-1.rs delete mode 100644 src/test/run-pass/unreachable-code.rs delete mode 100644 src/test/run-pass/unsafe-coercion.rs delete mode 100644 src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs delete mode 100644 src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs delete mode 100644 src/test/run-pass/unsafe-pointer-assignability.rs delete mode 100644 src/test/run-pass/unsized-locals/autoderef.rs delete mode 100644 src/test/run-pass/unsized-locals/box-fnonce.rs delete mode 100644 src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs delete mode 100644 src/test/run-pass/unsized-locals/reference-unsized-locals.rs delete mode 100644 src/test/run-pass/unsized-locals/simple-unsized-locals.rs delete mode 100644 src/test/run-pass/unsized-locals/unsized-parameters.rs delete mode 100644 src/test/run-pass/unsized-tuple-impls.rs delete mode 100644 src/test/run-pass/unsized.rs delete mode 100644 src/test/run-pass/unsized2.rs delete mode 100644 src/test/run-pass/unused-move-capture.rs delete mode 100644 src/test/run-pass/unused-move.rs delete mode 100644 src/test/run-pass/unwind-resource.rs delete mode 100644 src/test/run-pass/unwind-unique.rs delete mode 100644 src/test/run-pass/use-crate-name-alias.rs delete mode 100644 src/test/run-pass/use-import-export.rs delete mode 100644 src/test/run-pass/use-keyword-2.rs delete mode 100644 src/test/run-pass/use-mod.rs delete mode 100644 src/test/run-pass/use-nested-groups.rs delete mode 100644 src/test/run-pass/use.rs delete mode 100644 src/test/run-pass/use_inline_dtor.rs delete mode 100644 src/test/run-pass/using-target-feature-unstable.rs delete mode 100644 src/test/run-pass/utf8-bom.rs delete mode 100644 src/test/run-pass/utf8.rs delete mode 100644 src/test/run-pass/utf8_chars.rs delete mode 100644 src/test/run-pass/variadic-ffi.rs delete mode 100644 src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs delete mode 100644 src/test/run-pass/variance-iterators-in-libcore.rs delete mode 100644 src/test/run-pass/volatile-fat-ptr.rs delete mode 100644 src/test/run-pass/wait-forked-but-failed-child.rs delete mode 100644 src/test/run-pass/warn-ctypes-inhibit.rs delete mode 100644 src/test/run-pass/weak-lang-item.rs delete mode 100644 src/test/run-pass/weak-new-uninhabited-issue-48493.rs delete mode 100644 src/test/run-pass/weird-exit-code.rs delete mode 100644 src/test/run-pass/weird-exprs.rs delete mode 100644 src/test/run-pass/wf-bound-region-in-object-type.rs delete mode 100644 src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs delete mode 100644 src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs delete mode 100644 src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs delete mode 100644 src/test/run-pass/where-clauses/where-clause-region-outlives.rs delete mode 100644 src/test/run-pass/where-clauses/where-clauses-cross-crate.rs delete mode 100644 src/test/run-pass/where-clauses/where-clauses-lifetimes.rs delete mode 100644 src/test/run-pass/where-clauses/where-clauses-method.rs delete mode 100644 src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs delete mode 100644 src/test/run-pass/where-clauses/where-clauses.rs delete mode 100644 src/test/run-pass/wrapping-int-api.rs delete mode 100644 src/test/run-pass/write-fmt-errors.rs delete mode 100644 src/test/run-pass/writealias.rs delete mode 100644 src/test/run-pass/wrong-hashset-issue-42918.rs delete mode 100644 src/test/run-pass/x86stdcall.rs delete mode 100644 src/test/run-pass/x86stdcall2.rs delete mode 100644 src/test/run-pass/yield.rs delete mode 100644 src/test/run-pass/yield1.rs delete mode 100644 src/test/run-pass/yield2.rs delete mode 100644 src/test/run-pass/z-crate-attr.rs delete mode 100644 src/test/run-pass/zero-sized/zero-size-type-destructors.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs delete mode 100644 src/test/run-pass/zero-sized/zero-sized-vec-push.rs create mode 100644 src/test/ui-fulldeps/ast_stmt_expr_attr.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-13560-1.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-13560-2.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-13560-3.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-16822.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-18502.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-24106.rs create mode 100644 src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs create mode 100644 src/test/ui-fulldeps/auxiliary/linkage-visibility.rs create mode 100644 src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs create mode 100644 src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs create mode 100644 src/test/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs create mode 100644 src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs create mode 100644 src/test/ui-fulldeps/auxiliary/macro-crate-test.rs create mode 100644 src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs create mode 100644 src/test/ui-fulldeps/auxiliary/plugin-args.rs create mode 100644 src/test/ui-fulldeps/auxiliary/roman-numerals.rs create mode 100644 src/test/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs create mode 100644 src/test/ui-fulldeps/compiler-calls.rs create mode 100644 src/test/ui-fulldeps/create-dir-all-bare.rs create mode 100644 src/test/ui-fulldeps/derive-no-std-not-supported.rs create mode 100644 src/test/ui-fulldeps/deriving-encodable-decodable-box.rs create mode 100644 src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs create mode 100644 src/test/ui-fulldeps/deriving-global.rs create mode 100644 src/test/ui-fulldeps/deriving-hygiene.rs create mode 100644 src/test/ui-fulldeps/dropck_tarena_sound_drop.rs create mode 100644 src/test/ui-fulldeps/empty-struct-braces-derive.rs create mode 100644 src/test/ui-fulldeps/extern-mod-syntax.rs create mode 100644 src/test/ui-fulldeps/issue-11881.rs create mode 100644 src/test/ui-fulldeps/issue-13560.rs create mode 100644 src/test/ui-fulldeps/issue-14021.rs create mode 100644 src/test/ui-fulldeps/issue-15149.rs create mode 100644 src/test/ui-fulldeps/issue-15778-pass.rs create mode 100644 src/test/ui-fulldeps/issue-15924.rs create mode 100644 src/test/ui-fulldeps/issue-16822.rs create mode 100644 src/test/ui-fulldeps/issue-18502.rs create mode 100644 src/test/ui-fulldeps/issue-24106.rs create mode 100644 src/test/ui-fulldeps/issue-24972.rs create mode 100644 src/test/ui-fulldeps/issue-2804.rs create mode 100644 src/test/ui-fulldeps/issue-40001.rs create mode 100644 src/test/ui-fulldeps/issue-4016.rs create mode 100644 src/test/ui-fulldeps/issue-4036.rs create mode 100644 src/test/ui-fulldeps/linkage-visibility.rs create mode 100644 src/test/ui-fulldeps/llvm-pass-plugin.rs create mode 100644 src/test/ui-fulldeps/lto-syntax-extension.rs create mode 100644 src/test/ui-fulldeps/macro-crate-multi-decorator.rs create mode 100644 src/test/ui-fulldeps/mod_dir_path_canonicalized.rs create mode 100644 src/test/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir create mode 100644 src/test/ui-fulldeps/mod_dir_simple/test.rs create mode 100644 src/test/ui-fulldeps/myriad-closures.rs create mode 100644 src/test/ui-fulldeps/newtype_index.rs create mode 100644 src/test/ui-fulldeps/outlive-expansion-phase.rs create mode 100644 src/test/ui-fulldeps/plugin-args-1.rs create mode 100644 src/test/ui-fulldeps/plugin-args-2.rs create mode 100644 src/test/ui-fulldeps/plugin-args-3.rs create mode 100644 src/test/ui-fulldeps/pprust-expr-roundtrip.rs create mode 100644 src/test/ui-fulldeps/regions-mock-tcx.rs create mode 100644 src/test/ui-fulldeps/rename-directory.rs create mode 100644 src/test/ui-fulldeps/roman-numerals-macro.rs create mode 100644 src/test/ui-fulldeps/rustc_encodable_hygiene.rs create mode 100644 src/test/ui-fulldeps/stdio-from.rs create mode 100644 src/test/ui-fulldeps/switch-stdout.rs create mode 100644 src/test/ui-fulldeps/undef_mask.rs create mode 100644 src/test/ui/abi-sysv64-arg-passing.rs create mode 100644 src/test/ui/abi-sysv64-register-usage.rs create mode 100644 src/test/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs create mode 100644 src/test/ui/abort-on-c-abi.rs create mode 100644 src/test/ui/alias-uninit-value.rs create mode 100644 src/test/ui/align-with-extern-c-fn.rs create mode 100644 src/test/ui/alignment-gep-tup-like-1.rs create mode 100644 src/test/ui/alloca-from-derived-tydesc.rs create mode 100644 src/test/ui/allocator-alloc-one.rs create mode 100644 src/test/ui/allocator/auxiliary/custom-as-global.rs create mode 100644 src/test/ui/allocator/auxiliary/custom.rs create mode 100644 src/test/ui/allocator/auxiliary/helper.rs create mode 100644 src/test/ui/allocator/custom-in-block.rs create mode 100644 src/test/ui/allocator/custom-in-submodule.rs create mode 100644 src/test/ui/allocator/custom.rs create mode 100644 src/test/ui/allocator/xcrate-use.rs create mode 100644 src/test/ui/allocator/xcrate-use2.rs create mode 100644 src/test/ui/anon-extern-mod.rs create mode 100644 src/test/ui/argument-passing.rs create mode 100644 src/test/ui/array-slice-vec/arr_cycle.rs create mode 100644 src/test/ui/array-slice-vec/array_const_index-1.rs create mode 100644 src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs create mode 100644 src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs create mode 100644 src/test/ui/array-slice-vec/cast-in-array-size.rs create mode 100644 src/test/ui/array-slice-vec/check-static-mut-slices.rs create mode 100644 src/test/ui/array-slice-vec/check-static-slice.rs create mode 100644 src/test/ui/array-slice-vec/copy-out-of-array-1.rs create mode 100644 src/test/ui/array-slice-vec/destructure-array-1.rs create mode 100644 src/test/ui/array-slice-vec/empty-mutable-vec.rs create mode 100644 src/test/ui/array-slice-vec/estr-slice.rs create mode 100644 src/test/ui/array-slice-vec/evec-slice.rs create mode 100644 src/test/ui/array-slice-vec/fixed_length_copy.rs create mode 100644 src/test/ui/array-slice-vec/huge-largest-array.rs create mode 100644 src/test/ui/array-slice-vec/ivec-pass-by-value.rs create mode 100644 src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs create mode 100644 src/test/ui/array-slice-vec/mutable-alias-vec.rs create mode 100644 src/test/ui/array-slice-vec/nested-vec-1.rs create mode 100644 src/test/ui/array-slice-vec/nested-vec-2.rs create mode 100644 src/test/ui/array-slice-vec/nested-vec-3.rs create mode 100644 src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs create mode 100644 src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs create mode 100644 src/test/ui/array-slice-vec/repeated-vector-syntax.rs create mode 100644 src/test/ui/array-slice-vec/show-boxed-slice.rs create mode 100644 src/test/ui/array-slice-vec/slice-2.rs create mode 100644 src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs create mode 100644 src/test/ui/array-slice-vec/slice-panic-1.rs create mode 100644 src/test/ui/array-slice-vec/slice-panic-2.rs create mode 100644 src/test/ui/array-slice-vec/slice.rs create mode 100644 src/test/ui/array-slice-vec/slice_binary_search.rs create mode 100644 src/test/ui/array-slice-vec/variance-vec-covariant.rs create mode 100644 src/test/ui/array-slice-vec/vec-concat.rs create mode 100644 src/test/ui/array-slice-vec/vec-dst.rs create mode 100644 src/test/ui/array-slice-vec/vec-fixed-length.rs create mode 100644 src/test/ui/array-slice-vec/vec-growth.rs create mode 100644 src/test/ui/array-slice-vec/vec-late-init.rs create mode 100644 src/test/ui/array-slice-vec/vec-macro-no-std.rs create mode 100644 src/test/ui/array-slice-vec/vec-macro-repeat.rs create mode 100644 src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs create mode 100644 src/test/ui/array-slice-vec/vec-macro-with-brackets.rs create mode 100644 src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs create mode 100644 src/test/ui/array-slice-vec/vec-matching-autoslice.rs create mode 100644 src/test/ui/array-slice-vec/vec-matching-fixed.rs create mode 100644 src/test/ui/array-slice-vec/vec-matching-fold.rs create mode 100644 src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs create mode 100644 src/test/ui/array-slice-vec/vec-matching.rs create mode 100644 src/test/ui/array-slice-vec/vec-push.rs create mode 100644 src/test/ui/array-slice-vec/vec-repeat-with-cast.rs create mode 100644 src/test/ui/array-slice-vec/vec-slice-drop.rs create mode 100644 src/test/ui/array-slice-vec/vec-slice.rs create mode 100644 src/test/ui/array-slice-vec/vec-tail-matching.rs create mode 100644 src/test/ui/array-slice-vec/vec-to_str.rs create mode 100644 src/test/ui/array-slice-vec/vec.rs create mode 100644 src/test/ui/array-slice-vec/vec_cycle.rs create mode 100644 src/test/ui/array-slice-vec/vec_cycle_wrapped.rs create mode 100644 src/test/ui/array-slice-vec/vector-no-ann-2.rs create mode 100644 src/test/ui/artificial-block.rs create mode 100644 src/test/ui/as-precedence.rs create mode 100644 src/test/ui/asm-concat-src.rs create mode 100644 src/test/ui/asm-in-moved.rs create mode 100644 src/test/ui/asm-in-out-operand.rs create mode 100644 src/test/ui/asm-indirect-memory.rs create mode 100644 src/test/ui/asm-out-assign.rs create mode 100644 src/test/ui/assert-eq-trailing-comma.rs create mode 100644 src/test/ui/assert-escape.rs create mode 100644 src/test/ui/assert-ne-trailing-comma.rs create mode 100644 src/test/ui/assign-assign.rs create mode 100644 src/test/ui/assoc-oddities-3.rs create mode 100644 src/test/ui/associated-consts/associated-const-const-eval.rs create mode 100644 src/test/ui/associated-consts/associated-const-cross-crate-const-eval.rs create mode 100644 src/test/ui/associated-consts/associated-const-cross-crate-defaults.rs create mode 100644 src/test/ui/associated-consts/associated-const-cross-crate.rs create mode 100644 src/test/ui/associated-consts/associated-const-in-global-const.rs create mode 100644 src/test/ui/associated-consts/associated-const-inherent-impl.rs create mode 100644 src/test/ui/associated-consts/associated-const-marks-live-code.rs create mode 100644 src/test/ui/associated-consts/associated-const-match-patterns.rs create mode 100644 src/test/ui/associated-consts/associated-const-outer-ty-refs.rs create mode 100644 src/test/ui/associated-consts/associated-const-overwrite-default.rs create mode 100644 src/test/ui/associated-consts/associated-const-public-impl.rs create mode 100644 src/test/ui/associated-consts/associated-const-range-match-patterns.rs create mode 100644 src/test/ui/associated-consts/associated-const-resolution-order.rs create mode 100644 src/test/ui/associated-consts/associated-const-self-type.rs create mode 100644 src/test/ui/associated-consts/associated-const-type-parameters.rs create mode 100644 src/test/ui/associated-consts/associated-const-ufcs-infer-trait.rs create mode 100644 src/test/ui/associated-consts/associated-const-use-default.rs create mode 100644 src/test/ui/associated-consts/associated-const-use-impl-of-same-trait.rs create mode 100644 src/test/ui/associated-consts/associated-const.rs create mode 100644 src/test/ui/associated-consts/auxiliary/associated-const-cc-lib.rs create mode 100644 src/test/ui/associated-consts/auxiliary/empty-struct.rs create mode 100644 src/test/ui/associated-item-long-paths.rs create mode 100644 src/test/ui/associated-types/associated-types-basic.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-in-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-in-where-clause.rs create mode 100644 src/test/ui/associated-types/associated-types-bound.rs create mode 100644 src/test/ui/associated-types/associated-types-cc.rs create mode 100644 src/test/ui/associated-types/associated-types-conditional-dispatch.rs create mode 100644 src/test/ui/associated-types/associated-types-constant-type.rs create mode 100644 src/test/ui/associated-types/associated-types-doubleendediterator-object.rs create mode 100644 src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs create mode 100644 src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs create mode 100644 src/test/ui/associated-types/associated-types-enum-field-named.rs create mode 100644 src/test/ui/associated-types/associated-types-enum-field-numbered.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-obj.rs create mode 100644 src/test/ui/associated-types/associated-types-from-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-impl-redirect.rs create mode 100644 src/test/ui/associated-types/associated-types-in-bound-type-arg.rs create mode 100644 src/test/ui/associated-types/associated-types-in-default-method.rs create mode 100644 src/test/ui/associated-types/associated-types-in-fn.rs create mode 100644 src/test/ui/associated-types/associated-types-in-impl-generics.rs create mode 100644 src/test/ui/associated-types/associated-types-in-inherent-method.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-20220.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-20371.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-21212.rs create mode 100644 src/test/ui/associated-types/associated-types-iterator-binding.rs create mode 100644 src/test/ui/associated-types/associated-types-method.rs create mode 100644 src/test/ui/associated-types/associated-types-nested-projections.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs create mode 100644 src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-object-type.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-where-clause.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs create mode 100644 src/test/ui/associated-types/associated-types-ref-from-struct.rs create mode 100644 src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs create mode 100644 src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs create mode 100644 src/test/ui/associated-types/associated-types-resolve-lifetime.rs create mode 100644 src/test/ui/associated-types/associated-types-return.rs create mode 100644 src/test/ui/associated-types/associated-types-simple.rs create mode 100644 src/test/ui/associated-types/associated-types-stream.rs create mode 100644 src/test/ui/associated-types/associated-types-struct-field-named.rs create mode 100644 src/test/ui/associated-types/associated-types-struct-field-numbered.rs create mode 100644 src/test/ui/associated-types/associated-types-sugar-path.rs create mode 100644 src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs create mode 100644 src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs create mode 100644 src/test/ui/atomic-access-bool.rs create mode 100644 src/test/ui/atomic-alignment.rs create mode 100644 src/test/ui/atomic-compare_exchange.rs create mode 100644 src/test/ui/atomic-print.rs create mode 100644 src/test/ui/attr-main-2.rs create mode 100644 src/test/ui/attr-main.rs create mode 100644 src/test/ui/attr-shebang.rs create mode 100644 src/test/ui/attr-start.rs create mode 100644 src/test/ui/attr.rs create mode 100644 src/test/ui/augmented-assignments-feature-gate-cross.rs create mode 100644 src/test/ui/augmented-assignments-feature-gate.rs create mode 100644 src/test/ui/auto-instantiate.rs create mode 100644 src/test/ui/auto-is-contextual.rs create mode 100644 src/test/ui/autobind.rs create mode 100644 src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs create mode 100644 src/test/ui/autoref-autoderef/auto-ref-sliceable.rs create mode 100644 src/test/ui/autoref-autoderef/auto-ref.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-method-priority.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-method-twice.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-method.rs create mode 100644 src/test/ui/autoref-autoderef/autoderef-privacy.rs create mode 100644 src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs create mode 100644 src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/ui/auxiliary/augmented_assignments.rs create mode 100644 src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs create mode 100644 src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs create mode 100644 src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs create mode 100644 src/test/ui/auxiliary/cond_plugin.rs create mode 100644 src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs create mode 100644 src/test/ui/auxiliary/debuginfo-lto-aux.rs create mode 100644 src/test/ui/auxiliary/edition-kw-macro-2015.rs create mode 100644 src/test/ui/auxiliary/edition-kw-macro-2018.rs create mode 100644 src/test/ui/auxiliary/foreign_lib.rs create mode 100644 src/test/ui/auxiliary/hello_macro.rs create mode 100644 src/test/ui/auxiliary/impl_privacy_xc_1.rs create mode 100644 src/test/ui/auxiliary/impl_privacy_xc_2.rs create mode 100644 src/test/ui/auxiliary/inline_dtor.rs create mode 100644 src/test/ui/auxiliary/inner_static.rs create mode 100644 src/test/ui/auxiliary/kinds_in_metadata.rs create mode 100644 src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs create mode 100644 src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs create mode 100644 src/test/ui/auxiliary/linkage1.rs create mode 100644 src/test/ui/auxiliary/llvm_pr32379.rs create mode 100644 src/test/ui/auxiliary/msvc-data-only-lib.rs create mode 100644 src/test/ui/auxiliary/nested_item.rs create mode 100644 src/test/ui/auxiliary/proc_macro_def.rs create mode 100644 src/test/ui/auxiliary/reachable-unnameable-items.rs create mode 100644 src/test/ui/auxiliary/reexport-should-still-link.rs create mode 100644 src/test/ui/auxiliary/rmeta-rmeta.rs create mode 100644 src/test/ui/auxiliary/svh-a-base.rs create mode 100644 src/test/ui/auxiliary/svh-b.rs create mode 100644 src/test/ui/auxiliary/trait_superkinds_in_metadata.rs create mode 100644 src/test/ui/auxiliary/typeid-intrinsic-aux1.rs create mode 100644 src/test/ui/auxiliary/typeid-intrinsic-aux2.rs create mode 100644 src/test/ui/auxiliary/using-target-feature-unstable.rs create mode 100644 src/test/ui/backtrace-debuginfo-aux.rs create mode 100644 src/test/ui/backtrace-debuginfo.rs create mode 100644 src/test/ui/backtrace.rs create mode 100644 src/test/ui/bare-fn-implements-fn-mut.rs create mode 100644 src/test/ui/bare-static-string.rs create mode 100644 src/test/ui/bench/issue-32062.rs create mode 100644 src/test/ui/big-literals.rs create mode 100644 src/test/ui/binary-minus-without-space.rs create mode 100644 src/test/ui/bind-by-move.rs create mode 100644 src/test/ui/binding/bind-field-short-with-modifiers.rs create mode 100644 src/test/ui/binding/borrowed-ptr-pattern-2.rs create mode 100644 src/test/ui/binding/borrowed-ptr-pattern-3.rs create mode 100644 src/test/ui/binding/borrowed-ptr-pattern-infallible.rs create mode 100644 src/test/ui/binding/borrowed-ptr-pattern-option.rs create mode 100644 src/test/ui/binding/borrowed-ptr-pattern.rs create mode 100644 src/test/ui/binding/empty-types-in-patterns.rs create mode 100644 src/test/ui/binding/exhaustive-bool-match-sanity.rs create mode 100644 src/test/ui/binding/expr-match-generic-unique1.rs create mode 100644 src/test/ui/binding/expr-match-generic-unique2.rs create mode 100644 src/test/ui/binding/expr-match-generic.rs create mode 100644 src/test/ui/binding/expr-match-panic-all.rs create mode 100644 src/test/ui/binding/expr-match-panic.rs create mode 100644 src/test/ui/binding/expr-match-unique.rs create mode 100644 src/test/ui/binding/expr-match.rs create mode 100644 src/test/ui/binding/fat-arrow-match.rs create mode 100644 src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs create mode 100644 src/test/ui/binding/fn-pattern-expected-type-2.rs create mode 100644 src/test/ui/binding/fn-pattern-expected-type.rs create mode 100644 src/test/ui/binding/func-arg-incomplete-pattern.rs create mode 100644 src/test/ui/binding/func-arg-ref-pattern.rs create mode 100644 src/test/ui/binding/func-arg-wild-pattern.rs create mode 100644 src/test/ui/binding/if-let.rs create mode 100644 src/test/ui/binding/inconsistent-lifetime-mismatch.rs create mode 100644 src/test/ui/binding/inferred-suffix-in-pattern-range.rs create mode 100644 src/test/ui/binding/irrefutable-slice-patterns.rs create mode 100644 src/test/ui/binding/let-assignability.rs create mode 100644 src/test/ui/binding/let-destruct-ref.rs create mode 100644 src/test/ui/binding/let-var-hygiene.rs create mode 100644 src/test/ui/binding/match-arm-statics.rs create mode 100644 src/test/ui/binding/match-beginning-vert.rs create mode 100644 src/test/ui/binding/match-borrowed_str.rs create mode 100644 src/test/ui/binding/match-bot-2.rs create mode 100644 src/test/ui/binding/match-bot.rs create mode 100644 src/test/ui/binding/match-byte-array-patterns.rs create mode 100644 src/test/ui/binding/match-enum-struct-0.rs create mode 100644 src/test/ui/binding/match-enum-struct-1.rs create mode 100644 src/test/ui/binding/match-implicit-copy-unique.rs create mode 100644 src/test/ui/binding/match-in-macro.rs create mode 100644 src/test/ui/binding/match-join.rs create mode 100644 src/test/ui/binding/match-larger-const.rs create mode 100644 src/test/ui/binding/match-naked-record-expr.rs create mode 100644 src/test/ui/binding/match-naked-record.rs create mode 100644 src/test/ui/binding/match-path.rs create mode 100644 src/test/ui/binding/match-pattern-bindings.rs create mode 100644 src/test/ui/binding/match-pattern-lit.rs create mode 100644 src/test/ui/binding/match-pattern-no-type-params.rs create mode 100644 src/test/ui/binding/match-pattern-simple.rs create mode 100644 src/test/ui/binding/match-phi.rs create mode 100644 src/test/ui/binding/match-pipe-binding.rs create mode 100644 src/test/ui/binding/match-range-infer.rs create mode 100644 src/test/ui/binding/match-range-static.rs create mode 100644 src/test/ui/binding/match-range.rs create mode 100644 src/test/ui/binding/match-reassign.rs create mode 100644 src/test/ui/binding/match-ref-binding-in-guard-3256.rs create mode 100644 src/test/ui/binding/match-ref-binding-mut-option.rs create mode 100644 src/test/ui/binding/match-ref-binding-mut.rs create mode 100644 src/test/ui/binding/match-ref-binding.rs create mode 100644 src/test/ui/binding/match-ref-unsized.rs create mode 100644 src/test/ui/binding/match-str.rs create mode 100644 src/test/ui/binding/match-struct-0.rs create mode 100644 src/test/ui/binding/match-tag.rs create mode 100644 src/test/ui/binding/match-unique-bind.rs create mode 100644 src/test/ui/binding/match-unsized.rs create mode 100644 src/test/ui/binding/match-value-binding-in-guard-3291.rs create mode 100644 src/test/ui/binding/match-var-hygiene.rs create mode 100644 src/test/ui/binding/match-vec-alternatives.rs create mode 100644 src/test/ui/binding/match-vec-rvalue.rs create mode 100644 src/test/ui/binding/match-with-ret-arm.rs create mode 100644 src/test/ui/binding/multi-let.rs create mode 100644 src/test/ui/binding/mut-in-ident-patterns.rs create mode 100644 src/test/ui/binding/nested-exhaustive-match.rs create mode 100644 src/test/ui/binding/nested-matchs.rs create mode 100644 src/test/ui/binding/nested-pattern.rs create mode 100644 src/test/ui/binding/nil-pattern.rs create mode 100644 src/test/ui/binding/nullary-or-pattern.rs create mode 100644 src/test/ui/binding/optional_comma_in_match_arm.rs create mode 100644 src/test/ui/binding/or-pattern.rs create mode 100644 src/test/ui/binding/order-drop-with-match.rs create mode 100644 src/test/ui/binding/pat-ranges.rs create mode 100644 src/test/ui/binding/pat-tuple-1.rs create mode 100644 src/test/ui/binding/pat-tuple-2.rs create mode 100644 src/test/ui/binding/pat-tuple-3.rs create mode 100644 src/test/ui/binding/pat-tuple-4.rs create mode 100644 src/test/ui/binding/pat-tuple-5.rs create mode 100644 src/test/ui/binding/pat-tuple-6.rs create mode 100644 src/test/ui/binding/pat-tuple-7.rs create mode 100644 src/test/ui/binding/pattern-bound-var-in-for-each.rs create mode 100644 src/test/ui/binding/pattern-in-closure.rs create mode 100644 src/test/ui/binding/range-inclusive-pattern-precedence.rs create mode 100644 src/test/ui/binding/simple-generic-match.rs create mode 100644 src/test/ui/binding/use-uninit-match.rs create mode 100644 src/test/ui/binding/use-uninit-match2.rs create mode 100644 src/test/ui/binding/zero_sized_subslice_match.rs create mode 100644 src/test/ui/binops-issue-22743.rs create mode 100644 src/test/ui/binops.rs create mode 100644 src/test/ui/bitwise.rs create mode 100644 src/test/ui/blind-item-local-shadow.rs create mode 100644 src/test/ui/blind-item-mixed-crate-use-item.rs create mode 100644 src/test/ui/blind-item-mixed-use-item.rs create mode 100644 src/test/ui/block-arg-call-as.rs create mode 100644 src/test/ui/block-arg.rs create mode 100644 src/test/ui/block-explicit-types.rs create mode 100644 src/test/ui/block-expr-precedence.rs create mode 100644 src/test/ui/block-fn-coerce.rs create mode 100644 src/test/ui/block-iter-1.rs create mode 100644 src/test/ui/block-iter-2.rs create mode 100644 src/test/ui/bool-not.rs create mode 100644 src/test/ui/bool.rs create mode 100644 src/test/ui/borrow-by-val-method-receiver.rs create mode 100644 src/test/ui/borrowck/borrowck-assign-to-subfield.rs create mode 100644 src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs create mode 100644 src/test/ui/borrowck/borrowck-binding-mutbl.rs create mode 100644 src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs create mode 100644 src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs create mode 100644 src/test/ui/borrowck/borrowck-closures-two-imm.rs create mode 100644 src/test/ui/borrowck/borrowck-fixed-length-vecs.rs create mode 100644 src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs create mode 100644 src/test/ui/borrowck/borrowck-lend-args.rs create mode 100644 src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs create mode 100644 src/test/ui/borrowck/borrowck-move-by-capture-ok.rs create mode 100644 src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs create mode 100644 src/test/ui/borrowck/borrowck-mut-uniq.rs create mode 100644 src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs create mode 100644 src/test/ui/borrowck/borrowck-pat-enum.rs create mode 100644 src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs create mode 100644 src/test/ui/borrowck/borrowck-rvalues-mutable.rs create mode 100644 src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs create mode 100644 src/test/ui/borrowck/borrowck-static-item-in-fn.rs create mode 100644 src/test/ui/borrowck/borrowck-trait-lifetime.rs create mode 100644 src/test/ui/borrowck/borrowck-uniq-via-ref.rs create mode 100644 src/test/ui/borrowck/borrowck-univariant-enum.rs create mode 100644 src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs create mode 100644 src/test/ui/borrowck/borrowck-unused-mut-locals.rs create mode 100644 src/test/ui/borrowck/issue-62007-assign-box.rs create mode 100644 src/test/ui/borrowck/issue-62007-assign-field.rs create mode 100644 src/test/ui/borrowck/two-phase-baseline.rs create mode 100644 src/test/ui/borrowck/two-phase-bin-ops.rs create mode 100644 src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs create mode 100644 src/test/ui/box-new.rs create mode 100644 src/test/ui/bug-7183-generics.rs create mode 100644 src/test/ui/bug-7295.rs create mode 100644 src/test/ui/builtin-clone-unwind.rs create mode 100644 src/test/ui/builtin-clone.rs create mode 100644 src/test/ui/builtin-superkinds-capabilities-transitive.rs create mode 100644 src/test/ui/builtin-superkinds-capabilities-xc.rs create mode 100644 src/test/ui/builtin-superkinds-capabilities.rs create mode 100644 src/test/ui/builtin-superkinds-in-metadata.rs create mode 100644 src/test/ui/builtin-superkinds-phantom-typaram.rs create mode 100644 src/test/ui/builtin-superkinds-simple.rs create mode 100644 src/test/ui/builtin-superkinds-typaram.rs create mode 100644 src/test/ui/byte-literals.rs create mode 100644 src/test/ui/c-stack-as-value.rs create mode 100644 src/test/ui/c-stack-returning-int64.rs create mode 100644 src/test/ui/cabi-int-widening.rs create mode 100644 src/test/ui/can-copy-pod.rs create mode 100644 src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs create mode 100644 src/test/ui/cast-does-fallback.rs create mode 100644 src/test/ui/cast-region-to-uint.rs create mode 100644 src/test/ui/cast-rfc0401-vtable-kinds.rs create mode 100644 src/test/ui/cast-rfc0401.rs create mode 100644 src/test/ui/cast-to-infer-ty.rs create mode 100644 src/test/ui/cast.rs create mode 100644 src/test/ui/catch-unwind-bang.rs create mode 100644 src/test/ui/cell-does-not-clone.rs create mode 100644 src/test/ui/cfg/auxiliary/cfg_inner_static.rs create mode 100644 src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs create mode 100644 src/test/ui/cfg/cfg-attr-cfg.rs create mode 100644 src/test/ui/cfg/cfg-attr-crate.rs create mode 100644 src/test/ui/cfg/cfg-family.rs create mode 100644 src/test/ui/cfg/cfg-in-crate-1.rs create mode 100644 src/test/ui/cfg/cfg-macros-foo.rs create mode 100644 src/test/ui/cfg/cfg-macros-notfoo.rs create mode 100644 src/test/ui/cfg/cfg-match-arm.rs create mode 100644 src/test/ui/cfg/cfg-target-family.rs create mode 100644 src/test/ui/cfg/cfg-target-vendor.rs create mode 100644 src/test/ui/cfg/cfg_attr.rs create mode 100644 src/test/ui/cfg/cfg_inner_static.rs create mode 100644 src/test/ui/cfg/cfg_stmt_expr.rs create mode 100644 src/test/ui/cfg/cfgs-on-items.rs create mode 100644 src/test/ui/cfg/conditional-compile-arch.rs create mode 100644 src/test/ui/cfg/conditional-compile.rs create mode 100644 src/test/ui/cfg/crate-attributes-using-cfg_attr.rs create mode 100644 src/test/ui/chalkify/builtin-copy-clone.rs create mode 100644 src/test/ui/chalkify/inherent_impl.rs create mode 100644 src/test/ui/chalkify/projection.rs create mode 100644 src/test/ui/chalkify/super_trait.rs create mode 100644 src/test/ui/chalkify/trait_implied_bound.rs create mode 100644 src/test/ui/chalkify/type_implied_bound.rs create mode 100644 src/test/ui/char.rs create mode 100644 src/test/ui/char_unicode.rs create mode 100644 src/test/ui/check-static-recursion-foreign.rs create mode 100644 src/test/ui/check_const-feature-gated.rs create mode 100644 src/test/ui/child-outlives-parent.rs create mode 100644 src/test/ui/cleanup-arm-conditional.rs create mode 100644 src/test/ui/cleanup-rvalue-during-if-and-while.rs create mode 100644 src/test/ui/cleanup-rvalue-for-scope.rs create mode 100644 src/test/ui/cleanup-rvalue-scopes.rs create mode 100644 src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs create mode 100644 src/test/ui/cleanup-shortcircuit.rs create mode 100644 src/test/ui/clone-with-exterior.rs create mode 100644 src/test/ui/close-over-big-then-small-data.rs create mode 100644 src/test/ui/cmp-default.rs create mode 100644 src/test/ui/codegen-object-shim.rs create mode 100644 src/test/ui/coerce/coerce-expect-unsized.rs create mode 100644 src/test/ui/coerce/coerce-overloaded-autoderef.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs create mode 100644 src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs create mode 100644 src/test/ui/coerce/coerce-unify-return.rs create mode 100644 src/test/ui/coerce/coerce-unify.rs create mode 100644 src/test/ui/coerce/coerce-unsize-subtype.rs create mode 100644 src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs create mode 100644 src/test/ui/coherence/coherence-bigint-int.rs create mode 100644 src/test/ui/coherence/coherence-bigint-vecint.rs create mode 100644 src/test/ui/coherence/coherence-blanket.rs create mode 100644 src/test/ui/coherence/coherence-covered-type-parameter.rs create mode 100644 src/test/ui/coherence/coherence-impl-in-fn.rs create mode 100644 src/test/ui/coherence/coherence-iterator-vec-any-elem.rs create mode 100644 src/test/ui/coherence/coherence-iterator-vec.rs create mode 100644 src/test/ui/coherence/coherence-multidispatch-tuple.rs create mode 100644 src/test/ui/coherence/coherence-rfc447-constrained.rs create mode 100644 src/test/ui/coherence/coherence-where-clause.rs create mode 100644 src/test/ui/coherence/coherence_copy_like.rs create mode 100644 src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs create mode 100644 src/test/ui/collections-const-new.rs create mode 100644 src/test/ui/command-exec.rs create mode 100644 src/test/ui/command-pre-exec.rs create mode 100644 src/test/ui/command-uid-gid.rs create mode 100644 src/test/ui/complex.rs create mode 100644 src/test/ui/consts/assoc-const.rs create mode 100644 src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/ui/consts/auxiliary/cci_borrow_lib.rs create mode 100644 src/test/ui/consts/auxiliary/cci_const.rs create mode 100644 src/test/ui/consts/auxiliary/cci_const_block.rs create mode 100644 src/test/ui/consts/bswap-const.rs create mode 100644 src/test/ui/consts/chained-constants-stackoverflow.rs create mode 100644 src/test/ui/consts/const-adt-align-mismatch.rs create mode 100644 src/test/ui/consts/const-autoderef.rs create mode 100644 src/test/ui/consts/const-big-enum.rs create mode 100644 src/test/ui/consts/const-binops.rs create mode 100644 src/test/ui/consts/const-bitshift-rhs-inference.rs create mode 100644 src/test/ui/consts/const-block-cross-crate-fn.rs create mode 100644 src/test/ui/consts/const-block-item-macro-codegen.rs create mode 100644 src/test/ui/consts/const-block-item.rs create mode 100644 src/test/ui/consts/const-block-non-item-statement-3.rs create mode 100644 src/test/ui/consts/const-block.rs create mode 100644 src/test/ui/consts/const-bound.rs create mode 100644 src/test/ui/consts/const-byte-str-cast.rs create mode 100644 src/test/ui/consts/const-cast-ptr-int.rs create mode 100644 src/test/ui/consts/const-cast.rs create mode 100644 src/test/ui/consts/const-const.rs create mode 100644 src/test/ui/consts/const-contents.rs create mode 100644 src/test/ui/consts/const-cross-crate-const.rs create mode 100644 src/test/ui/consts/const-cross-crate-extern.rs create mode 100644 src/test/ui/consts/const-deref.rs create mode 100644 src/test/ui/consts/const-endianess.rs create mode 100644 src/test/ui/consts/const-enum-byref-self.rs create mode 100644 src/test/ui/consts/const-enum-byref.rs create mode 100644 src/test/ui/consts/const-enum-cast.rs create mode 100644 src/test/ui/consts/const-enum-ptr.rs create mode 100644 src/test/ui/consts/const-enum-struct.rs create mode 100644 src/test/ui/consts/const-enum-struct2.rs create mode 100644 src/test/ui/consts/const-enum-structlike.rs create mode 100644 src/test/ui/consts/const-enum-tuple.rs create mode 100644 src/test/ui/consts/const-enum-tuple2.rs create mode 100644 src/test/ui/consts/const-enum-tuplestruct.rs create mode 100644 src/test/ui/consts/const-enum-tuplestruct2.rs create mode 100644 src/test/ui/consts/const-enum-vec-index.rs create mode 100644 src/test/ui/consts/const-enum-vec-ptr.rs create mode 100644 src/test/ui/consts/const-enum-vector.rs create mode 100644 src/test/ui/consts/const-expr-in-fixed-length-vec.rs create mode 100644 src/test/ui/consts/const-expr-in-vec-repeat.rs create mode 100644 src/test/ui/consts/const-extern-function.rs create mode 100644 src/test/ui/consts/const-fields-and-indexing.rs create mode 100644 src/test/ui/consts/const-fn-const-eval.rs create mode 100644 src/test/ui/consts/const-fn-feature-flags.rs create mode 100644 src/test/ui/consts/const-fn-method.rs create mode 100644 src/test/ui/consts/const-fn-nested.rs create mode 100644 src/test/ui/consts/const-fn-stability-calls.rs create mode 100644 src/test/ui/consts/const-fn-type-name.rs create mode 100644 src/test/ui/consts/const-fn-val.rs create mode 100644 src/test/ui/consts/const-fn.rs create mode 100644 src/test/ui/consts/const-index-feature-gate.rs create mode 100644 src/test/ui/consts/const-int-saturating-arith.rs create mode 100644 src/test/ui/consts/const-meth-pattern.rs create mode 100644 src/test/ui/consts/const-needs_drop.rs create mode 100644 src/test/ui/consts/const-negation.rs create mode 100644 src/test/ui/consts/const-negative.rs create mode 100644 src/test/ui/consts/const-nullary-enum.rs create mode 100644 src/test/ui/consts/const-nullary-univariant-enum.rs create mode 100644 src/test/ui/consts/const-pattern-variant.rs create mode 100644 src/test/ui/consts/const-rec-and-tup.rs create mode 100644 src/test/ui/consts/const-region-ptrs-noncopy.rs create mode 100644 src/test/ui/consts/const-region-ptrs.rs create mode 100644 src/test/ui/consts/const-repeated-values.rs create mode 100644 src/test/ui/consts/const-size_of-align_of.rs create mode 100644 src/test/ui/consts/const-str-ptr.rs create mode 100644 src/test/ui/consts/const-struct-offsets.rs create mode 100644 src/test/ui/consts/const-struct.rs create mode 100644 src/test/ui/consts/const-trait-to-trait.rs create mode 100644 src/test/ui/consts/const-tuple-struct.rs create mode 100644 src/test/ui/consts/const-unit-struct.rs create mode 100644 src/test/ui/consts/const-unsafe-fn.rs create mode 100644 src/test/ui/consts/const-vec-of-fns.rs create mode 100644 src/test/ui/consts/const-vec-syntax.rs create mode 100644 src/test/ui/consts/const-vecs-and-slices.rs create mode 100644 src/test/ui/consts/const.rs create mode 100644 src/test/ui/consts/consts-in-patterns.rs create mode 100644 src/test/ui/consts/deref_in_pattern.rs create mode 100644 src/test/ui/consts/ice-48279.rs create mode 100644 src/test/ui/consts/issue-37550.rs create mode 100644 src/test/ui/consts/issue-broken-mir.rs create mode 100644 src/test/ui/consts/locals-in-const-fn.rs create mode 100644 src/test/ui/consts/match-const-fn-structs.rs create mode 100644 src/test/ui/consts/mozjs-error.rs create mode 100644 src/test/ui/consts/non-scalar-cast.rs create mode 100644 src/test/ui/consts/promotion.rs create mode 100644 src/test/ui/consts/references.rs create mode 100644 src/test/ui/consts/repeat_match.rs create mode 100644 src/test/ui/consts/return-in-const-fn.rs create mode 100644 src/test/ui/consts/signed_enum_discr.rs create mode 100644 src/test/ui/consts/transmute-const.rs create mode 100644 src/test/ui/consts/tuple-struct-constructors.rs create mode 100644 src/test/ui/core-run-destroy.rs create mode 100644 src/test/ui/crate-leading-sep.rs create mode 100644 src/test/ui/crate-method-reexport-grrrrrrr.rs create mode 100644 src/test/ui/crate-name-attr-used.rs create mode 100644 src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs create mode 100644 src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_const.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs create mode 100644 src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs create mode 100644 src/test/ui/cross-crate/auxiliary/pub_static_array.rs create mode 100644 src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs create mode 100644 src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs create mode 100644 src/test/ui/cross-crate/cci_borrow.rs create mode 100644 src/test/ui/cross-crate/cci_capture_clause.rs create mode 100644 src/test/ui/cross-crate/cci_impl_exe.rs create mode 100644 src/test/ui/cross-crate/cci_iter_exe.rs create mode 100644 src/test/ui/cross-crate/cci_nested_exe.rs create mode 100644 src/test/ui/cross-crate/cci_no_inline_exe.rs create mode 100644 src/test/ui/cross-crate/cross-crate-const-pat.rs create mode 100644 src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs create mode 100644 src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs create mode 100644 src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs create mode 100644 src/test/ui/cross-crate/static-array-across-crate.rs create mode 100644 src/test/ui/cross-crate/xcrate-address-insignificant.rs create mode 100644 src/test/ui/cross-crate/xcrate-associated-type-defaults.rs create mode 100644 src/test/ui/cross-crate/xcrate-static-addresses.rs create mode 100644 src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs create mode 100644 src/test/ui/cross-crate/xcrate-unit-struct.rs create mode 100644 src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs create mode 100644 src/test/ui/crt-static-off-works.rs create mode 100644 src/test/ui/crt-static-on-works.rs create mode 100644 src/test/ui/cycle-generic-bound.rs create mode 100644 src/test/ui/dead-code-alias-in-pat.rs create mode 100644 src/test/ui/dead-code-leading-underscore.rs create mode 100644 src/test/ui/debuginfo-lto.rs create mode 100644 src/test/ui/deep.rs create mode 100644 src/test/ui/default-alloc-error-hook.rs create mode 100644 src/test/ui/default-associated-types.rs create mode 100644 src/test/ui/default-method-parsing.rs create mode 100644 src/test/ui/default-method-simple.rs create mode 100644 src/test/ui/defaults-well-formedness.rs create mode 100644 src/test/ui/deprecation-in-force-unstable.rs create mode 100644 src/test/ui/deref-lval.rs create mode 100644 src/test/ui/deref-mut-on-ref.rs create mode 100644 src/test/ui/deref-on-ref.rs create mode 100644 src/test/ui/deref-rc.rs create mode 100644 src/test/ui/deref.rs create mode 100644 src/test/ui/deriving/auxiliary/derive-no-std.rs create mode 100644 src/test/ui/deriving/derive-no-std.rs create mode 100644 src/test/ui/deriving/derive-partialord-correctness.rs create mode 100644 src/test/ui/deriving/deriving-associated-types.rs create mode 100644 src/test/ui/deriving/deriving-bounds.rs create mode 100644 src/test/ui/deriving/deriving-clone-array.rs create mode 100644 src/test/ui/deriving/deriving-clone-enum.rs create mode 100644 src/test/ui/deriving/deriving-clone-generic-enum.rs create mode 100644 src/test/ui/deriving/deriving-clone-generic-struct.rs create mode 100644 src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs create mode 100644 src/test/ui/deriving/deriving-clone-struct.rs create mode 100644 src/test/ui/deriving/deriving-clone-tuple-struct.rs create mode 100644 src/test/ui/deriving/deriving-cmp-generic-enum.rs create mode 100644 src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs create mode 100644 src/test/ui/deriving/deriving-cmp-generic-struct.rs create mode 100644 src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs create mode 100644 src/test/ui/deriving/deriving-cmp-shortcircuit.rs create mode 100644 src/test/ui/deriving/deriving-copyclone.rs create mode 100644 src/test/ui/deriving/deriving-default-box.rs create mode 100644 src/test/ui/deriving/deriving-enum-single-variant.rs create mode 100644 src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs create mode 100644 src/test/ui/deriving/deriving-hash.rs create mode 100644 src/test/ui/deriving/deriving-in-fn.rs create mode 100644 src/test/ui/deriving/deriving-in-macro.rs create mode 100644 src/test/ui/deriving/deriving-meta-multiple.rs create mode 100644 src/test/ui/deriving/deriving-meta.rs create mode 100644 src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs create mode 100644 src/test/ui/deriving/deriving-show-2.rs create mode 100644 src/test/ui/deriving/deriving-show.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-c-enum.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-enum.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-hash-enum.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-hash-struct.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-struct-empty.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-struct-tuple.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-struct.rs create mode 100644 src/test/ui/deriving/deriving-via-extension-type-params.rs create mode 100644 src/test/ui/deriving/deriving-with-repr-packed.rs create mode 100644 src/test/ui/dispatch_from_dyn_zst.rs create mode 100644 src/test/ui/diverging-fallback-control-flow.rs create mode 100644 src/test/ui/diverging-fallback-method-chain.rs create mode 100644 src/test/ui/diverging-fallback-option.rs create mode 100644 src/test/ui/double-ref.rs create mode 100644 src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs create mode 100644 src/test/ui/drop/drop-on-empty-block-exit.rs create mode 100644 src/test/ui/drop/drop-on-ret.rs create mode 100644 src/test/ui/drop/drop-struct-as-object.rs create mode 100644 src/test/ui/drop/drop-trait-enum.rs create mode 100644 src/test/ui/drop/drop-trait-generic.rs create mode 100644 src/test/ui/drop/drop-trait.rs create mode 100644 src/test/ui/drop/drop-uninhabited-enum.rs create mode 100644 src/test/ui/drop/drop-with-type-ascription-1.rs create mode 100644 src/test/ui/drop/drop-with-type-ascription-2.rs create mode 100644 src/test/ui/drop/dropck-eyepatch-extern-crate.rs create mode 100644 src/test/ui/drop/dropck-eyepatch-reorder.rs create mode 100644 src/test/ui/drop/dropck-eyepatch.rs create mode 100644 src/test/ui/drop/dropck_legal_cycles.rs create mode 100644 src/test/ui/drop/dynamic-drop-async.rs create mode 100644 src/test/ui/drop/dynamic-drop.rs create mode 100644 src/test/ui/drop/no-drop-flag-size.rs create mode 100644 src/test/ui/drop/nondrop-cycle.rs create mode 100644 src/test/ui/dupe-first-attr.rc create mode 100644 src/test/ui/duplicated-external-mods.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-coerce-custom.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-coerce-rc.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-coercions.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-deref-mut.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-deref.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-field-align.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-index.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-raw.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-struct-sole.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-struct.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-trait-tuple.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-trait.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-tuple-sole.rs create mode 100644 src/test/ui/dynamically-sized-types/dst-tuple.rs create mode 100644 src/test/ui/early-ret-binop-add.rs create mode 100644 src/test/ui/early-vtbl-resolution.rs create mode 100644 src/test/ui/edition-keywords-2015-2015.rs create mode 100644 src/test/ui/edition-keywords-2015-2018.rs create mode 100644 src/test/ui/edition-keywords-2018-2015.rs create mode 100644 src/test/ui/edition-keywords-2018-2018.rs create mode 100644 src/test/ui/else-if.rs create mode 100644 src/test/ui/empty-allocation-non-null.rs create mode 100644 src/test/ui/empty-allocation-rvalue-non-null.rs create mode 100644 src/test/ui/empty-type-parameter-list.rs create mode 100644 src/test/ui/empty_global_asm.rs create mode 100644 src/test/ui/env-args-reverse-iterator.rs create mode 100644 src/test/ui/env-funky-keys.rs create mode 100644 src/test/ui/env-home-dir.rs create mode 100644 src/test/ui/env-null-vars.rs create mode 100644 src/test/ui/env-vars.rs create mode 100644 src/test/ui/epoch-gate-feature.rs create mode 100644 src/test/ui/eq-multidispatch.rs create mode 100644 src/test/ui/estr-uniq.rs create mode 100644 src/test/ui/exec-env.rs create mode 100644 src/test/ui/existential_type.rs create mode 100644 src/test/ui/explicit-i-suffix.rs create mode 100644 src/test/ui/export-glob-imports-target.rs create mode 100644 src/test/ui/export-multi.rs create mode 100644 src/test/ui/export-non-interference2.rs create mode 100644 src/test/ui/export-non-interference3.rs create mode 100644 src/test/ui/expr-block-fn.rs create mode 100644 src/test/ui/expr-block-generic-unique1.rs create mode 100644 src/test/ui/expr-block-generic-unique2.rs create mode 100644 src/test/ui/expr-block-generic.rs create mode 100644 src/test/ui/expr-block-slot.rs create mode 100644 src/test/ui/expr-block-unique.rs create mode 100644 src/test/ui/expr-block.rs create mode 100644 src/test/ui/expr-copy.rs create mode 100644 src/test/ui/expr-empty-ret.rs create mode 100644 src/test/ui/expr-fn.rs create mode 100644 src/test/ui/expr-if-generic.rs create mode 100644 src/test/ui/expr-if-panic-all.rs create mode 100644 src/test/ui/expr-if-panic.rs create mode 100644 src/test/ui/expr-if-unique.rs create mode 100644 src/test/ui/expr-if.rs create mode 100644 src/test/ui/expr-scope.rs create mode 100644 src/test/ui/ext-expand-inner-exprs.rs create mode 100644 src/test/ui/extend-for-unit.rs create mode 100644 src/test/ui/exterior.rs create mode 100644 src/test/ui/extern/auxiliary/extern-crosscrate-source.rs create mode 100644 src/test/ui/extern/auxiliary/extern-take-value.rs create mode 100644 src/test/ui/extern/auxiliary/extern_calling_convention.rs create mode 100644 src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs create mode 100644 src/test/ui/extern/auxiliary/fat_drop.rs create mode 100644 src/test/ui/extern/extern-1.rs create mode 100644 src/test/ui/extern/extern-call-deep.rs create mode 100644 src/test/ui/extern/extern-call-deep2.rs create mode 100644 src/test/ui/extern/extern-call-direct.rs create mode 100644 src/test/ui/extern/extern-call-indirect.rs create mode 100644 src/test/ui/extern/extern-call-scrub.rs create mode 100644 src/test/ui/extern/extern-calling-convention-test.rs create mode 100644 src/test/ui/extern/extern-compare-with-return-type.rs create mode 100644 src/test/ui/extern/extern-crosscrate.rs create mode 100644 src/test/ui/extern/extern-foreign-crate.rs create mode 100644 src/test/ui/extern/extern-methods.rs create mode 100644 src/test/ui/extern/extern-mod-abi.rs create mode 100644 src/test/ui/extern/extern-mod-ordering-exe.rs create mode 100644 src/test/ui/extern/extern-pass-TwoU16s.rs create mode 100644 src/test/ui/extern/extern-pass-TwoU32s.rs create mode 100644 src/test/ui/extern/extern-pass-TwoU64s.rs create mode 100644 src/test/ui/extern/extern-pass-TwoU8s.rs create mode 100644 src/test/ui/extern/extern-pass-char.rs create mode 100644 src/test/ui/extern/extern-pass-double.rs create mode 100644 src/test/ui/extern/extern-pass-empty.rs create mode 100644 src/test/ui/extern/extern-pass-u32.rs create mode 100644 src/test/ui/extern/extern-pass-u64.rs create mode 100644 src/test/ui/extern/extern-prelude-core.rs create mode 100644 src/test/ui/extern/extern-prelude-core.stderr create mode 100644 src/test/ui/extern/extern-prelude-no-speculative.rs create mode 100644 src/test/ui/extern/extern-prelude-std.rs create mode 100644 src/test/ui/extern/extern-prelude-std.stderr create mode 100644 src/test/ui/extern/extern-pub.rs create mode 100644 src/test/ui/extern/extern-return-TwoU16s.rs create mode 100644 src/test/ui/extern/extern-return-TwoU32s.rs create mode 100644 src/test/ui/extern/extern-return-TwoU64s.rs create mode 100644 src/test/ui/extern/extern-return-TwoU8s.rs create mode 100644 src/test/ui/extern/extern-rust.rs create mode 100644 src/test/ui/extern/extern-take-value.rs create mode 100644 src/test/ui/extern/extern-thiscall.rs create mode 100644 src/test/ui/extern/extern-types-inherent-impl.rs create mode 100644 src/test/ui/extern/extern-types-manual-sync-send.rs create mode 100644 src/test/ui/extern/extern-types-pointer-cast.rs create mode 100644 src/test/ui/extern/extern-types-size_of_val.rs create mode 100644 src/test/ui/extern/extern-types-thin-pointer.rs create mode 100644 src/test/ui/extern/extern-types-trait-impl.rs create mode 100644 src/test/ui/extern/extern-vectorcall.rs create mode 100644 src/test/ui/extern/extern_fat_drop.rs create mode 100644 src/test/ui/extoption_env-not-defined.rs create mode 100644 src/test/ui/fact.rs create mode 100644 src/test/ui/fat-lto.rs create mode 100644 src/test/ui/fds-are-cloexec.rs create mode 100644 src/test/ui/filter-block-view-items.rs create mode 100644 src/test/ui/fixup-deref-mut.rs create mode 100644 src/test/ui/for-loop-while/auto-loop.rs create mode 100644 src/test/ui/for-loop-while/break-value.rs create mode 100644 src/test/ui/for-loop-while/break.rs create mode 100644 src/test/ui/for-loop-while/for-destruct.rs create mode 100644 src/test/ui/for-loop-while/for-loop-goofiness.rs create mode 100644 src/test/ui/for-loop-while/for-loop-has-unit-body.rs create mode 100644 src/test/ui/for-loop-while/for-loop-into-iterator.rs create mode 100644 src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs create mode 100644 src/test/ui/for-loop-while/for-loop-macro.rs create mode 100644 src/test/ui/for-loop-while/for-loop-mut-ref-element.rs create mode 100644 src/test/ui/for-loop-while/for-loop-no-std.rs create mode 100644 src/test/ui/for-loop-while/for-loop-panic.rs create mode 100644 src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators-break.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators-loop.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators-nested.rs create mode 100644 src/test/ui/for-loop-while/foreach-external-iterators.rs create mode 100644 src/test/ui/for-loop-while/foreach-nested.rs create mode 100644 src/test/ui/for-loop-while/foreach-put-structured.rs create mode 100644 src/test/ui/for-loop-while/foreach-simple-outer-slot.rs create mode 100644 src/test/ui/for-loop-while/label_break_value.rs create mode 100644 src/test/ui/for-loop-while/labeled-break.rs create mode 100644 src/test/ui/for-loop-while/linear-for-loop.rs create mode 100644 src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs create mode 100644 src/test/ui/for-loop-while/liveness-loop-break.rs create mode 100644 src/test/ui/for-loop-while/liveness-move-in-loop.rs create mode 100644 src/test/ui/for-loop-while/loop-break-cont-1.rs create mode 100644 src/test/ui/for-loop-while/loop-break-cont.rs create mode 100644 src/test/ui/for-loop-while/loop-break-value.rs create mode 100644 src/test/ui/for-loop-while/loop-diverges.rs create mode 100644 src/test/ui/for-loop-while/loop-label-shadowing.rs create mode 100644 src/test/ui/for-loop-while/loop-labeled-break-value.rs create mode 100644 src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs create mode 100644 src/test/ui/for-loop-while/loop-scope.rs create mode 100644 src/test/ui/for-loop-while/while-cont.rs create mode 100644 src/test/ui/for-loop-while/while-flow-graph.rs create mode 100644 src/test/ui/for-loop-while/while-label.rs create mode 100644 src/test/ui/for-loop-while/while-let.rs create mode 100644 src/test/ui/for-loop-while/while-loop-constraints-2.rs create mode 100644 src/test/ui/for-loop-while/while-prelude-drop.rs create mode 100644 src/test/ui/for-loop-while/while-with-break.rs create mode 100644 src/test/ui/for-loop-while/while.rs create mode 100644 src/test/ui/foreign/auxiliary/fn-abi.rs create mode 100644 src/test/ui/foreign/auxiliary/foreign_lib.rs create mode 100644 src/test/ui/foreign/foreign-call-no-runtime.rs create mode 100644 src/test/ui/foreign/foreign-dupe.rs create mode 100644 src/test/ui/foreign/foreign-fn-linkname.rs create mode 100644 src/test/ui/foreign/foreign-fn-with-byval.rs create mode 100644 src/test/ui/foreign/foreign-int-types.rs create mode 100644 src/test/ui/foreign/foreign-mod-src/compiletest-ignore-dir create mode 100644 src/test/ui/foreign/foreign-mod-src/inner.rs create mode 100644 src/test/ui/foreign/foreign-mod-unused-const.rs create mode 100644 src/test/ui/foreign/foreign-no-abi.rs create mode 100644 src/test/ui/foreign/foreign-src/compiletest-ignore-dir create mode 100644 src/test/ui/foreign/foreign-src/foreign.rs create mode 100644 src/test/ui/foreign/foreign-truncated-arguments.rs create mode 100644 src/test/ui/foreign/foreign2.rs create mode 100644 src/test/ui/format-hygiene.rs create mode 100644 src/test/ui/format-nan.rs create mode 100644 src/test/ui/format-no-std.rs create mode 100644 src/test/ui/format-ref-cell.rs create mode 100644 src/test/ui/fsu-moves-and-copies.rs create mode 100644 src/test/ui/fun-call-variants.rs create mode 100644 src/test/ui/fun-indirect-call.rs create mode 100644 src/test/ui/functions-closures/auxiliary/fn-abi.rs create mode 100644 src/test/ui/functions-closures/call-closure-from-overloaded-op.rs create mode 100644 src/test/ui/functions-closures/capture-clauses-boxed-closures.rs create mode 100644 src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs create mode 100644 src/test/ui/functions-closures/clone-closure.rs create mode 100644 src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs create mode 100644 src/test/ui/functions-closures/closure-expected-type/README.md create mode 100644 src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs create mode 100644 src/test/ui/functions-closures/closure-expected-type/issue-38714.rs create mode 100644 src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs create mode 100644 src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs create mode 100644 src/test/ui/functions-closures/closure-immediate.rs create mode 100644 src/test/ui/functions-closures/closure-inference.rs create mode 100644 src/test/ui/functions-closures/closure-inference2.rs create mode 100644 src/test/ui/functions-closures/closure-reform.rs create mode 100644 src/test/ui/functions-closures/closure-returning-closure.rs create mode 100644 src/test/ui/functions-closures/closure-to-fn-coercion.rs create mode 100644 src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs create mode 100644 src/test/ui/functions-closures/copy-closure.rs create mode 100644 src/test/ui/functions-closures/fn-abi.rs create mode 100644 src/test/ui/functions-closures/fn-bare-assign.rs create mode 100644 src/test/ui/functions-closures/fn-bare-coerce-to-block.rs create mode 100644 src/test/ui/functions-closures/fn-bare-item.rs create mode 100644 src/test/ui/functions-closures/fn-bare-size.rs create mode 100644 src/test/ui/functions-closures/fn-bare-spawn.rs create mode 100644 src/test/ui/functions-closures/fn-coerce-field.rs create mode 100644 src/test/ui/functions-closures/fn-item-type-cast.rs create mode 100644 src/test/ui/functions-closures/fn-item-type-coerce.rs create mode 100644 src/test/ui/functions-closures/fn-item-type-zero-sized.rs create mode 100644 src/test/ui/functions-closures/fn-lval.rs create mode 100644 src/test/ui/functions-closures/fn-type-infer.rs create mode 100644 src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs create mode 100644 src/test/ui/functions-closures/nullable-pointer-opt-closures.rs create mode 100644 src/test/ui/functions-closures/parallel-codegen-closures.rs create mode 100644 src/test/ui/functions-closures/return-from-closure.rs create mode 100644 src/test/ui/generator/addassign-yield.rs create mode 100644 src/test/ui/generator/auxiliary/xcrate-reachable.rs create mode 100644 src/test/ui/generator/auxiliary/xcrate.rs create mode 100644 src/test/ui/generator/borrow-in-tail-expr.rs create mode 100644 src/test/ui/generator/conditional-drop.rs create mode 100644 src/test/ui/generator/control-flow.rs create mode 100644 src/test/ui/generator/drop-and-replace.rs create mode 100644 src/test/ui/generator/drop-env.rs create mode 100644 src/test/ui/generator/issue-44197.rs create mode 100644 src/test/ui/generator/issue-52398.rs create mode 100644 src/test/ui/generator/issue-57084.rs create mode 100644 src/test/ui/generator/issue-58888.rs create mode 100644 src/test/ui/generator/iterator-count.rs create mode 100644 src/test/ui/generator/live-upvar-across-yield.rs create mode 100644 src/test/ui/generator/match-bindings.rs create mode 100644 src/test/ui/generator/nested_generators.rs create mode 100644 src/test/ui/generator/non-static-is-unpin.rs create mode 100644 src/test/ui/generator/overlap-locals.rs create mode 100644 src/test/ui/generator/panic-drops.rs create mode 100644 src/test/ui/generator/panic-safe.rs create mode 100644 src/test/ui/generator/pin-box-generator.rs create mode 100644 src/test/ui/generator/reborrow-mut-upvar.rs create mode 100644 src/test/ui/generator/resume-after-return.rs create mode 100644 src/test/ui/generator/size-moved-locals.rs create mode 100644 src/test/ui/generator/smoke.rs create mode 100644 src/test/ui/generator/static-generators.rs create mode 100644 src/test/ui/generator/too-live-local-in-immovable-gen.rs create mode 100644 src/test/ui/generator/xcrate-reachable.rs create mode 100644 src/test/ui/generator/xcrate.rs create mode 100644 src/test/ui/generator/yield-in-args-rev.rs create mode 100644 src/test/ui/generator/yield-in-box.rs create mode 100644 src/test/ui/generator/yield-in-initializer.rs create mode 100644 src/test/ui/generator/yield-subtype.rs create mode 100644 src/test/ui/generics/auxiliary/default_type_params_xc.rs create mode 100644 src/test/ui/generics/generic-alias-unique.rs create mode 100644 src/test/ui/generics/generic-default-type-params-cross-crate.rs create mode 100644 src/test/ui/generics/generic-default-type-params.rs create mode 100644 src/test/ui/generics/generic-derived-type.rs create mode 100644 src/test/ui/generics/generic-exterior-unique.rs create mode 100644 src/test/ui/generics/generic-extern-mangle.rs create mode 100644 src/test/ui/generics/generic-fn-infer.rs create mode 100644 src/test/ui/generics/generic-fn-twice.rs create mode 100644 src/test/ui/generics/generic-fn-unique.rs create mode 100644 src/test/ui/generics/generic-fn.rs create mode 100644 src/test/ui/generics/generic-ivec-leak.rs create mode 100644 src/test/ui/generics/generic-newtype-struct.rs create mode 100644 src/test/ui/generics/generic-object.rs create mode 100644 src/test/ui/generics/generic-recursive-tag.rs create mode 100644 src/test/ui/generics/generic-static-methods.rs create mode 100644 src/test/ui/generics/generic-tag-corruption.rs create mode 100644 src/test/ui/generics/generic-tag-local.rs create mode 100644 src/test/ui/generics/generic-tag-match.rs create mode 100644 src/test/ui/generics/generic-tag-values.rs create mode 100644 src/test/ui/generics/generic-tag.rs create mode 100644 src/test/ui/generics/generic-temporary.rs create mode 100644 src/test/ui/generics/generic-tup.rs create mode 100644 src/test/ui/generics/generic-type-synonym.rs create mode 100644 src/test/ui/generics/generic-type.rs create mode 100644 src/test/ui/generics/generic-unique.rs create mode 100644 src/test/ui/global-scope.rs create mode 100644 src/test/ui/guards-not-exhaustive.rs create mode 100644 src/test/ui/guards.rs create mode 100644 src/test/ui/hashmap-memory.rs create mode 100644 src/test/ui/hello.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs create mode 100644 src/test/ui/html-literals.rs create mode 100644 src/test/ui/if-bot.rs create mode 100644 src/test/ui/if-check.rs create mode 100644 src/test/ui/if-ret.rs create mode 100644 src/test/ui/ifmt.rs create mode 100644 src/test/ui/ignore-all-the-things.rs create mode 100644 src/test/ui/impl-for-never.rs create mode 100644 src/test/ui/impl-inherent-non-conflict.rs create mode 100644 src/test/ui/impl-not-adjacent-to-type.rs create mode 100644 src/test/ui/impl-privacy-xc-1.rs create mode 100644 src/test/ui/impl-privacy-xc-2.rs create mode 100644 src/test/ui/impl-trait-in-bindings.rs create mode 100644 src/test/ui/impl-trait-in-bindings.stderr create mode 100644 src/test/ui/impl-trait/auxiliary/xcrate.rs create mode 100644 src/test/ui/impl-trait/bounds_regression.rs create mode 100644 src/test/ui/impl-trait/example-calendar.rs create mode 100644 src/test/ui/impl-trait/example-st.rs create mode 100644 src/test/ui/impl-trait/lifetimes.rs create mode 100644 src/test/ui/impl-trait/nesting.rs create mode 100644 src/test/ui/impl-trait/universal_hrtb_anon.rs create mode 100644 src/test/ui/impl-trait/universal_hrtb_named.rs create mode 100644 src/test/ui/impl-trait/universal_in_adt_in_parameters.rs create mode 100644 src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs create mode 100644 src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs create mode 100644 src/test/ui/impl-trait/universal_multiple_bounds.rs create mode 100644 src/test/ui/impl-trait/xcrate.rs create mode 100644 src/test/ui/impl-trait/xcrate_simple.rs create mode 100644 src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs create mode 100644 src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs create mode 100644 src/test/ui/imports/import-crate-with-invalid-spans/main.rs create mode 100644 src/test/ui/imports/import-from.rs create mode 100644 src/test/ui/imports/import-glob-1.rs create mode 100644 src/test/ui/imports/import-glob-crate.rs create mode 100644 src/test/ui/imports/import-in-block.rs create mode 100644 src/test/ui/imports/import-prefix-macro.rs create mode 100644 src/test/ui/imports/import-rename.rs create mode 100644 src/test/ui/imports/import-trailing-comma.rs create mode 100644 src/test/ui/imports/import.rs create mode 100644 src/test/ui/imports/import2.rs create mode 100644 src/test/ui/imports/import3.rs create mode 100644 src/test/ui/imports/import4.rs create mode 100644 src/test/ui/imports/import5.rs create mode 100644 src/test/ui/imports/import6.rs create mode 100644 src/test/ui/imports/import7.rs create mode 100644 src/test/ui/imports/import8.rs create mode 100644 src/test/ui/imports/imports.rs create mode 100644 src/test/ui/in-band-lifetimes.rs create mode 100644 src/test/ui/inc-range-pat.rs create mode 100644 src/test/ui/infer-fn-tail-expr.rs create mode 100644 src/test/ui/inherit-env.rs create mode 100644 src/test/ui/init-large-type.rs create mode 100644 src/test/ui/init-res-into-things.rs create mode 100644 src/test/ui/inlined-main.rs create mode 100644 src/test/ui/inner-attrs-on-impl.rs create mode 100644 src/test/ui/inner-module.rs create mode 100644 src/test/ui/inner-static.rs create mode 100644 src/test/ui/instantiable.rs create mode 100644 src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs create mode 100644 src/test/ui/intrinsics/intrinsic-alignment.rs create mode 100644 src/test/ui/intrinsics/intrinsic-assume.rs create mode 100644 src/test/ui/intrinsics/intrinsic-atomics-cc.rs create mode 100644 src/test/ui/intrinsics/intrinsic-atomics.rs create mode 100644 src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs create mode 100644 src/test/ui/intrinsics/intrinsic-move-val.rs create mode 100644 src/test/ui/intrinsics/intrinsic-unreachable.rs create mode 100644 src/test/ui/intrinsics/intrinsics-integer.rs create mode 100644 src/test/ui/intrinsics/intrinsics-math.rs create mode 100644 src/test/ui/invalid_const_promotion.rs create mode 100644 src/test/ui/invoke-external-foreign.rs create mode 100644 src/test/ui/irrefutable-unit.rs create mode 100644 src/test/ui/issue-59020.rs create mode 100644 src/test/ui/issues/.gitattributes create mode 100644 src/test/ui/issues/auxiliary/cgu_test.rs create mode 100644 src/test/ui/issues/auxiliary/cgu_test_a.rs create mode 100644 src/test/ui/issues/auxiliary/cgu_test_b.rs create mode 100644 src/test/ui/issues/auxiliary/i8.rs create mode 100644 src/test/ui/issues/auxiliary/iss.rs create mode 100644 src/test/ui/issues/auxiliary/issue-10028.rs create mode 100644 src/test/ui/issues/auxiliary/issue-10031-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11224.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11225-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11225-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11225-3.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11508.rs create mode 100644 src/test/ui/issues/auxiliary/issue-11529.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12133-dylib.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12133-dylib2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12133-rlib.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12612-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12612-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-12660-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13507.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13620-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13620-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13872-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13872-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-13872-3.rs create mode 100644 src/test/ui/issues/auxiliary/issue-14344-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-14344-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-14421.rs create mode 100644 src/test/ui/issues/auxiliary/issue-14422.rs create mode 100644 src/test/ui/issues/auxiliary/issue-15562.rs create mode 100644 src/test/ui/issues/auxiliary/issue-16643.rs create mode 100644 src/test/ui/issues/auxiliary/issue-17662.rs create mode 100644 src/test/ui/issues/auxiliary/issue-17718-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-18501.rs create mode 100644 src/test/ui/issues/auxiliary/issue-18514.rs create mode 100644 src/test/ui/issues/auxiliary/issue-18711.rs create mode 100644 src/test/ui/issues/auxiliary/issue-18913-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-18913-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-19293.rs create mode 100644 src/test/ui/issues/auxiliary/issue-19340-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-20389.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2170-lib.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2316-a.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2316-b.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2380.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2414-a.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2414-b.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2472-b.rs create mode 100644 src/test/ui/issues/auxiliary/issue-25185-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-25185-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2526.rs create mode 100644 src/test/ui/issues/auxiliary/issue-25467.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2631-a.rs create mode 100644 src/test/ui/issues/auxiliary/issue-2723-a.rs create mode 100644 src/test/ui/issues/auxiliary/issue-29485.rs create mode 100644 src/test/ui/issues/auxiliary/issue-3012-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-3136-a.rc create mode 100644 src/test/ui/issues/auxiliary/issue-3136-a.rs create mode 100644 src/test/ui/issues/auxiliary/issue-31702-1.rs create mode 100644 src/test/ui/issues/auxiliary/issue-31702-2.rs create mode 100644 src/test/ui/issues/auxiliary/issue-34796-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-36954.rs create mode 100644 src/test/ui/issues/auxiliary/issue-38190.rs create mode 100644 src/test/ui/issues/auxiliary/issue-38226-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-38715-modern.rs create mode 100644 src/test/ui/issues/auxiliary/issue-38715.rs create mode 100644 src/test/ui/issues/auxiliary/issue-3979-traits.rs create mode 100644 src/test/ui/issues/auxiliary/issue-39823.rs create mode 100644 src/test/ui/issues/auxiliary/issue-40469.rs create mode 100644 src/test/ui/issues/auxiliary/issue-41053.rs create mode 100644 src/test/ui/issues/auxiliary/issue-41394.rs create mode 100644 src/test/ui/issues/auxiliary/issue-42007-s.rs create mode 100644 src/test/ui/issues/auxiliary/issue-4208-cc.rs create mode 100644 src/test/ui/issues/auxiliary/issue-4545.rs create mode 100644 src/test/ui/issues/auxiliary/issue-48984-aux.rs create mode 100644 src/test/ui/issues/auxiliary/issue-5518.rs create mode 100644 src/test/ui/issues/auxiliary/issue-5521.rs create mode 100644 src/test/ui/issues/auxiliary/issue-7178.rs create mode 100644 src/test/ui/issues/auxiliary/issue-7899.rs create mode 100644 src/test/ui/issues/auxiliary/issue-8044.rs create mode 100644 src/test/ui/issues/auxiliary/issue-8259.rs create mode 100644 src/test/ui/issues/auxiliary/issue-8401.rs create mode 100644 src/test/ui/issues/auxiliary/issue-9123.rs create mode 100644 src/test/ui/issues/auxiliary/issue-9155.rs create mode 100644 src/test/ui/issues/auxiliary/issue-9188.rs create mode 100644 src/test/ui/issues/auxiliary/issue-9906.rs create mode 100644 src/test/ui/issues/auxiliary/issue-9968.rs create mode 100644 src/test/ui/issues/issue-10025.rs create mode 100644 src/test/ui/issues/issue-10028.rs create mode 100644 src/test/ui/issues/issue-10031.rs create mode 100644 src/test/ui/issues/issue-10228.rs create mode 100644 src/test/ui/issues/issue-10392.rs create mode 100644 src/test/ui/issues/issue-10436.rs create mode 100644 src/test/ui/issues/issue-10626.rs create mode 100644 src/test/ui/issues/issue-10638.rs create mode 100644 src/test/ui/issues/issue-10682.rs create mode 100644 src/test/ui/issues/issue-10683.rs create mode 100644 src/test/ui/issues/issue-10718.rs create mode 100644 src/test/ui/issues/issue-10734.rs create mode 100644 src/test/ui/issues/issue-10767.rs create mode 100644 src/test/ui/issues/issue-10802.rs create mode 100644 src/test/ui/issues/issue-10806.rs create mode 100644 src/test/ui/issues/issue-11047.rs create mode 100644 src/test/ui/issues/issue-11085.rs create mode 100644 src/test/ui/issues/issue-1112.rs create mode 100644 src/test/ui/issues/issue-11205.rs create mode 100644 src/test/ui/issues/issue-11224.rs create mode 100644 src/test/ui/issues/issue-11225-1.rs create mode 100644 src/test/ui/issues/issue-11225-2.rs create mode 100644 src/test/ui/issues/issue-11225-3.rs create mode 100644 src/test/ui/issues/issue-11267.rs create mode 100644 src/test/ui/issues/issue-11382.rs create mode 100644 src/test/ui/issues/issue-11508.rs create mode 100644 src/test/ui/issues/issue-11529.rs create mode 100644 src/test/ui/issues/issue-11552.rs create mode 100644 src/test/ui/issues/issue-11577.rs create mode 100644 src/test/ui/issues/issue-11677.rs create mode 100644 src/test/ui/issues/issue-11709.rs create mode 100644 src/test/ui/issues/issue-11820.rs create mode 100644 src/test/ui/issues/issue-11940.rs create mode 100644 src/test/ui/issues/issue-11958.rs create mode 100644 src/test/ui/issues/issue-12033.rs create mode 100644 src/test/ui/issues/issue-12133-1.rs create mode 100644 src/test/ui/issues/issue-12133-2.rs create mode 100644 src/test/ui/issues/issue-12133-3.rs create mode 100644 src/test/ui/issues/issue-12285.rs create mode 100644 src/test/ui/issues/issue-1257.rs create mode 100644 src/test/ui/issues/issue-12582.rs create mode 100644 src/test/ui/issues/issue-12612.rs create mode 100644 src/test/ui/issues/issue-12660.rs create mode 100644 src/test/ui/issues/issue-12677.rs create mode 100644 src/test/ui/issues/issue-12699.rs create mode 100644 src/test/ui/issues/issue-12744.rs create mode 100644 src/test/ui/issues/issue-12860.rs create mode 100644 src/test/ui/issues/issue-12909.rs create mode 100644 src/test/ui/issues/issue-13027.rs create mode 100644 src/test/ui/issues/issue-13204.rs create mode 100644 src/test/ui/issues/issue-13259-windows-tcb-trash.rs create mode 100644 src/test/ui/issues/issue-13264.rs create mode 100644 src/test/ui/issues/issue-13304.rs create mode 100644 src/test/ui/issues/issue-13323.rs create mode 100644 src/test/ui/issues/issue-13434.rs create mode 100644 src/test/ui/issues/issue-13507-2.rs create mode 100644 src/test/ui/issues/issue-13620.rs create mode 100644 src/test/ui/issues/issue-13655.rs create mode 100644 src/test/ui/issues/issue-13665.rs create mode 100644 src/test/ui/issues/issue-13763.rs create mode 100644 src/test/ui/issues/issue-13808.rs create mode 100644 src/test/ui/issues/issue-13867.rs create mode 100644 src/test/ui/issues/issue-13872.rs create mode 100644 src/test/ui/issues/issue-13902.rs create mode 100644 src/test/ui/issues/issue-14229.rs create mode 100644 src/test/ui/issues/issue-14308.rs create mode 100644 src/test/ui/issues/issue-14344.rs create mode 100644 src/test/ui/issues/issue-14382.rs create mode 100644 src/test/ui/issues/issue-14393.rs create mode 100644 src/test/ui/issues/issue-14399.rs create mode 100644 src/test/ui/issues/issue-14421.rs create mode 100644 src/test/ui/issues/issue-14422.rs create mode 100644 src/test/ui/issues/issue-14456.rs create mode 100644 src/test/ui/issues/issue-1451.rs create mode 100644 src/test/ui/issues/issue-14589.rs create mode 100644 src/test/ui/issues/issue-1460.rs create mode 100644 src/test/ui/issues/issue-14821.rs create mode 100644 src/test/ui/issues/issue-14865.rs create mode 100644 src/test/ui/issues/issue-14875.rs create mode 100644 src/test/ui/issues/issue-14919.rs create mode 100644 src/test/ui/issues/issue-14940.rs create mode 100644 src/test/ui/issues/issue-14958.rs create mode 100644 src/test/ui/issues/issue-15043.rs create mode 100644 src/test/ui/issues/issue-15063.rs create mode 100644 src/test/ui/issues/issue-15080.rs create mode 100644 src/test/ui/issues/issue-15104.rs create mode 100644 src/test/ui/issues/issue-15155.rs create mode 100644 src/test/ui/issues/issue-15189.rs create mode 100644 src/test/ui/issues/issue-15221.rs create mode 100644 src/test/ui/issues/issue-15444.rs create mode 100644 src/test/ui/issues/issue-15487.rs create mode 100644 src/test/ui/issues/issue-15523-big.rs create mode 100644 src/test/ui/issues/issue-15523.rs create mode 100644 src/test/ui/issues/issue-15562.rs create mode 100644 src/test/ui/issues/issue-15571.rs create mode 100644 src/test/ui/issues/issue-15673.rs create mode 100644 src/test/ui/issues/issue-15689-1.rs create mode 100644 src/test/ui/issues/issue-15730.rs create mode 100644 src/test/ui/issues/issue-15734.rs create mode 100644 src/test/ui/issues/issue-15763.rs create mode 100644 src/test/ui/issues/issue-15774.rs create mode 100644 src/test/ui/issues/issue-15793.rs create mode 100644 src/test/ui/issues/issue-15858.rs create mode 100644 src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs create mode 100644 src/test/ui/issues/issue-16151.rs create mode 100644 src/test/ui/issues/issue-16256.rs create mode 100644 src/test/ui/issues/issue-16272.rs create mode 100644 src/test/ui/issues/issue-16278.rs create mode 100644 src/test/ui/issues/issue-16441.rs create mode 100644 src/test/ui/issues/issue-16452.rs create mode 100644 src/test/ui/issues/issue-16492.rs create mode 100644 src/test/ui/issues/issue-16530.rs create mode 100644 src/test/ui/issues/issue-16560.rs create mode 100644 src/test/ui/issues/issue-16597-empty.rs create mode 100644 src/test/ui/issues/issue-16597.rs create mode 100644 src/test/ui/issues/issue-1660.rs create mode 100644 src/test/ui/issues/issue-16602-1.rs create mode 100644 src/test/ui/issues/issue-16602-2.rs create mode 100644 src/test/ui/issues/issue-16602-3.rs create mode 100644 src/test/ui/issues/issue-16643.rs create mode 100644 src/test/ui/issues/issue-16648.rs create mode 100644 src/test/ui/issues/issue-16671.rs create mode 100644 src/test/ui/issues/issue-16739.rs create mode 100644 src/test/ui/issues/issue-16745.rs create mode 100644 src/test/ui/issues/issue-16774.rs create mode 100644 src/test/ui/issues/issue-16783.rs create mode 100644 src/test/ui/issues/issue-16819.rs create mode 100644 src/test/ui/issues/issue-1696.rs create mode 100644 src/test/ui/issues/issue-1701.rs create mode 100644 src/test/ui/issues/issue-17068.rs create mode 100644 src/test/ui/issues/issue-17074.rs create mode 100644 src/test/ui/issues/issue-17170.rs create mode 100644 src/test/ui/issues/issue-17216.rs create mode 100644 src/test/ui/issues/issue-17233.rs create mode 100644 src/test/ui/issues/issue-17302.rs create mode 100644 src/test/ui/issues/issue-17322.rs create mode 100644 src/test/ui/issues/issue-17351.rs create mode 100644 src/test/ui/issues/issue-17361.rs create mode 100644 src/test/ui/issues/issue-17503.rs create mode 100644 src/test/ui/issues/issue-17662.rs create mode 100644 src/test/ui/issues/issue-17718-borrow-interior.rs create mode 100644 src/test/ui/issues/issue-17718-parse-const.rs create mode 100644 src/test/ui/issues/issue-17718-static-unsafe-interior.rs create mode 100644 src/test/ui/issues/issue-17718.rs create mode 100644 src/test/ui/issues/issue-17734.rs create mode 100644 src/test/ui/issues/issue-17756.rs create mode 100644 src/test/ui/issues/issue-17771.rs create mode 100644 src/test/ui/issues/issue-17816.rs create mode 100644 src/test/ui/issues/issue-17877.rs create mode 100644 src/test/ui/issues/issue-17897.rs create mode 100644 src/test/ui/issues/issue-18060.rs create mode 100644 src/test/ui/issues/issue-18075.rs create mode 100644 src/test/ui/issues/issue-18110.rs create mode 100644 src/test/ui/issues/issue-18173.rs create mode 100644 src/test/ui/issues/issue-18232.rs create mode 100644 src/test/ui/issues/issue-18352.rs create mode 100644 src/test/ui/issues/issue-18353.rs create mode 100644 src/test/ui/issues/issue-18412.rs create mode 100644 src/test/ui/issues/issue-18425.rs create mode 100644 src/test/ui/issues/issue-18464.rs create mode 100644 src/test/ui/issues/issue-18501.rs create mode 100644 src/test/ui/issues/issue-18514.rs create mode 100644 src/test/ui/issues/issue-18539.rs create mode 100644 src/test/ui/issues/issue-18652.rs create mode 100644 src/test/ui/issues/issue-18655.rs create mode 100644 src/test/ui/issues/issue-18661.rs create mode 100644 src/test/ui/issues/issue-18685.rs create mode 100644 src/test/ui/issues/issue-18711.rs create mode 100644 src/test/ui/issues/issue-18767.rs create mode 100644 src/test/ui/issues/issue-18804/auxiliary/lib.rs create mode 100644 src/test/ui/issues/issue-18804/main.rs create mode 100644 src/test/ui/issues/issue-18845.rs create mode 100644 src/test/ui/issues/issue-18859.rs create mode 100644 src/test/ui/issues/issue-18913.rs create mode 100644 src/test/ui/issues/issue-18937-1.rs create mode 100644 src/test/ui/issues/issue-18952.rs create mode 100644 src/test/ui/issues/issue-19001.rs create mode 100644 src/test/ui/issues/issue-19127.rs create mode 100644 src/test/ui/issues/issue-19135.rs create mode 100644 src/test/ui/issues/issue-19244.rs create mode 100644 src/test/ui/issues/issue-19293.rs create mode 100644 src/test/ui/issues/issue-19340-1.rs create mode 100644 src/test/ui/issues/issue-19340-2.rs create mode 100644 src/test/ui/issues/issue-19358.rs create mode 100644 src/test/ui/issues/issue-19367.rs create mode 100644 src/test/ui/issues/issue-19499.rs create mode 100644 src/test/ui/issues/issue-1974.rs create mode 100644 src/test/ui/issues/issue-19811-escape-unicode.rs create mode 100644 src/test/ui/issues/issue-20055-box-trait.rs create mode 100644 src/test/ui/issues/issue-20055-box-unsized-array.rs create mode 100644 src/test/ui/issues/issue-20174.rs create mode 100644 src/test/ui/issues/issue-20343.rs create mode 100644 src/test/ui/issues/issue-20389.rs create mode 100644 src/test/ui/issues/issue-20427.rs create mode 100644 src/test/ui/issues/issue-20544.rs create mode 100644 src/test/ui/issues/issue-20575.rs create mode 100644 src/test/ui/issues/issue-20616.rs create mode 100644 src/test/ui/issues/issue-2063.rs create mode 100644 src/test/ui/issues/issue-20676.rs create mode 100644 src/test/ui/issues/issue-2074.rs create mode 100644 src/test/ui/issues/issue-20803.rs create mode 100644 src/test/ui/issues/issue-20823.rs create mode 100644 src/test/ui/issues/issue-20847.rs create mode 100644 src/test/ui/issues/issue-20953.rs create mode 100644 src/test/ui/issues/issue-21033.rs create mode 100644 src/test/ui/issues/issue-21058.rs create mode 100644 src/test/ui/issues/issue-21291.rs create mode 100644 src/test/ui/issues/issue-21306.rs create mode 100644 src/test/ui/issues/issue-21361.rs create mode 100644 src/test/ui/issues/issue-21384.rs create mode 100644 src/test/ui/issues/issue-21400.rs create mode 100644 src/test/ui/issues/issue-21475.rs create mode 100644 src/test/ui/issues/issue-21486.rs create mode 100644 src/test/ui/issues/issue-21655.rs create mode 100644 src/test/ui/issues/issue-2170-exe.rs create mode 100644 src/test/ui/issues/issue-21721.rs create mode 100644 src/test/ui/issues/issue-2190-1.rs create mode 100644 src/test/ui/issues/issue-21909.rs create mode 100644 src/test/ui/issues/issue-21922.rs create mode 100644 src/test/ui/issues/issue-22008.rs create mode 100644 src/test/ui/issues/issue-22036.rs create mode 100644 src/test/ui/issues/issue-2214.rs create mode 100644 src/test/ui/issues/issue-2216.rs create mode 100644 src/test/ui/issues/issue-22258.rs create mode 100644 src/test/ui/issues/issue-22346.rs create mode 100644 src/test/ui/issues/issue-22403.rs create mode 100644 src/test/ui/issues/issue-22426.rs create mode 100644 src/test/ui/issues/issue-22463.rs create mode 100644 src/test/ui/issues/issue-22536-copy-mustnt-zero.rs create mode 100644 src/test/ui/issues/issue-22546.rs create mode 100644 src/test/ui/issues/issue-22577.rs create mode 100644 src/test/ui/issues/issue-22629.rs create mode 100644 src/test/ui/issues/issue-22828.rs create mode 100644 src/test/ui/issues/issue-2284.rs create mode 100644 src/test/ui/issues/issue-22864-1.rs create mode 100644 src/test/ui/issues/issue-22864-2.rs create mode 100644 src/test/ui/issues/issue-2288.rs create mode 100644 src/test/ui/issues/issue-22992-2.rs create mode 100644 src/test/ui/issues/issue-22992.rs create mode 100644 src/test/ui/issues/issue-23036.rs create mode 100644 src/test/ui/issues/issue-2316-c.rs create mode 100644 src/test/ui/issues/issue-23208.rs create mode 100644 src/test/ui/issues/issue-23261.rs create mode 100644 src/test/ui/issues/issue-23304-1.rs create mode 100644 src/test/ui/issues/issue-23304-2.rs create mode 100644 src/test/ui/issues/issue-23311.rs create mode 100644 src/test/ui/issues/issue-23336.rs create mode 100644 src/test/ui/issues/issue-23338-ensure-param-drop-order.rs create mode 100644 src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs create mode 100644 src/test/ui/issues/issue-23433.rs create mode 100644 src/test/ui/issues/issue-23485.rs create mode 100644 src/test/ui/issues/issue-23491.rs create mode 100644 src/test/ui/issues/issue-23611-enum-swap-in-drop.rs create mode 100644 src/test/ui/issues/issue-23649-1.rs create mode 100644 src/test/ui/issues/issue-23649-2.rs create mode 100644 src/test/ui/issues/issue-23699.rs create mode 100644 src/test/ui/issues/issue-23781.rs create mode 100644 src/test/ui/issues/issue-2380-b.rs create mode 100644 src/test/ui/issues/issue-23808.rs create mode 100644 src/test/ui/issues/issue-23825.rs create mode 100644 src/test/ui/issues/issue-2383.rs create mode 100644 src/test/ui/issues/issue-23833.rs create mode 100644 src/test/ui/issues/issue-23891.rs create mode 100644 src/test/ui/issues/issue-23898.rs create mode 100644 src/test/ui/issues/issue-23958.rs create mode 100644 src/test/ui/issues/issue-23968-const-not-overflow.rs create mode 100644 src/test/ui/issues/issue-23992.rs create mode 100644 src/test/ui/issues/issue-24010.rs create mode 100644 src/test/ui/issues/issue-24086.rs create mode 100644 src/test/ui/issues/issue-2414-c.rs create mode 100644 src/test/ui/issues/issue-2428.rs create mode 100644 src/test/ui/issues/issue-24308.rs create mode 100644 src/test/ui/issues/issue-24313.rs create mode 100644 src/test/ui/issues/issue-24353.rs create mode 100644 src/test/ui/issues/issue-2445-b.rs create mode 100644 src/test/ui/issues/issue-2445.rs create mode 100644 src/test/ui/issues/issue-24533.rs create mode 100644 src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs create mode 100644 src/test/ui/issues/issue-24589.rs create mode 100644 src/test/ui/issues/issue-2463.rs create mode 100644 src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs create mode 100644 src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs create mode 100644 src/test/ui/issues/issue-24687-embed-debuginfo/main.rs create mode 100644 src/test/ui/issues/issue-2472.rs create mode 100644 src/test/ui/issues/issue-24779.rs create mode 100644 src/test/ui/issues/issue-24805-dropck-itemless.rs create mode 100644 src/test/ui/issues/issue-24945-repeat-dash-opts.rs create mode 100644 src/test/ui/issues/issue-24947.rs create mode 100644 src/test/ui/issues/issue-24954.rs create mode 100644 src/test/ui/issues/issue-25089.rs create mode 100644 src/test/ui/issues/issue-25145.rs create mode 100644 src/test/ui/issues/issue-25185.rs create mode 100644 src/test/ui/issues/issue-2526-a.rs create mode 100644 src/test/ui/issues/issue-25279.rs create mode 100644 src/test/ui/issues/issue-25339.rs create mode 100644 src/test/ui/issues/issue-25343.rs create mode 100644 src/test/ui/issues/issue-25467.rs create mode 100644 src/test/ui/issues/issue-25497.rs create mode 100644 src/test/ui/issues/issue-2550.rs create mode 100644 src/test/ui/issues/issue-25515.rs create mode 100644 src/test/ui/issues/issue-25549-multiple-drop.rs create mode 100644 src/test/ui/issues/issue-25679.rs create mode 100644 src/test/ui/issues/issue-25693.rs create mode 100644 src/test/ui/issues/issue-25700-1.rs create mode 100644 src/test/ui/issues/issue-25700-2.rs create mode 100644 src/test/ui/issues/issue-25746-bool-transmute.rs create mode 100644 src/test/ui/issues/issue-25757.rs create mode 100644 src/test/ui/issues/issue-25810.rs create mode 100644 src/test/ui/issues/issue-25916.rs create mode 100644 src/test/ui/issues/issue-26127.rs create mode 100644 src/test/ui/issues/issue-26251.rs create mode 100644 src/test/ui/issues/issue-2631-b.rs create mode 100644 src/test/ui/issues/issue-26322.rs create mode 100644 src/test/ui/issues/issue-2633-2.rs create mode 100644 src/test/ui/issues/issue-2633.rs create mode 100644 src/test/ui/issues/issue-2642.rs create mode 100644 src/test/ui/issues/issue-26468.rs create mode 100644 src/test/ui/issues/issue-26484.rs create mode 100644 src/test/ui/issues/issue-26641.rs create mode 100644 src/test/ui/issues/issue-26655.rs create mode 100644 src/test/ui/issues/issue-26709.rs create mode 100644 src/test/ui/issues/issue-26802.rs create mode 100644 src/test/ui/issues/issue-26805.rs create mode 100644 src/test/ui/issues/issue-26873-multifile.rs create mode 100644 src/test/ui/issues/issue-26873-multifile/A/B.rs create mode 100644 src/test/ui/issues/issue-26873-multifile/A/C.rs create mode 100644 src/test/ui/issues/issue-26873-multifile/A/mod.rs create mode 100644 src/test/ui/issues/issue-26873-multifile/compiletest-ignore-dir create mode 100644 src/test/ui/issues/issue-26873-multifile/mod.rs create mode 100644 src/test/ui/issues/issue-26873-onefile.rs create mode 100644 src/test/ui/issues/issue-26996.rs create mode 100644 src/test/ui/issues/issue-27021.rs create mode 100644 src/test/ui/issues/issue-27054-primitive-binary-ops.rs create mode 100644 src/test/ui/issues/issue-2708.rs create mode 100644 src/test/ui/issues/issue-2718.rs create mode 100644 src/test/ui/issues/issue-2723-b.rs create mode 100644 src/test/ui/issues/issue-27240.rs create mode 100644 src/test/ui/issues/issue-27268.rs create mode 100644 src/test/ui/issues/issue-27320.rs create mode 100644 src/test/ui/issues/issue-2734.rs create mode 100644 src/test/ui/issues/issue-2735-2.rs create mode 100644 src/test/ui/issues/issue-2735-3.rs create mode 100644 src/test/ui/issues/issue-2735.rs create mode 100644 src/test/ui/issues/issue-27401-dropflag-reinit.rs create mode 100644 src/test/ui/issues/issue-2748-b.rs create mode 100644 src/test/ui/issues/issue-27639.rs create mode 100644 src/test/ui/issues/issue-27859.rs create mode 100644 src/test/ui/issues/issue-27890.rs create mode 100644 src/test/ui/issues/issue-27901.rs create mode 100644 src/test/ui/issues/issue-27949.rs create mode 100644 src/test/ui/issues/issue-27997.rs create mode 100644 src/test/ui/issues/issue-28181.rs create mode 100644 src/test/ui/issues/issue-28498-must-work-ex1.rs create mode 100644 src/test/ui/issues/issue-28498-must-work-ex2.rs create mode 100644 src/test/ui/issues/issue-28498-ugeh-ex1.rs create mode 100644 src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs create mode 100644 src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs create mode 100644 src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs create mode 100644 src/test/ui/issues/issue-28550.rs create mode 100644 src/test/ui/issues/issue-28676.rs create mode 100644 src/test/ui/issues/issue-28777.rs create mode 100644 src/test/ui/issues/issue-28828.rs create mode 100644 src/test/ui/issues/issue-28839.rs create mode 100644 src/test/ui/issues/issue-2895.rs create mode 100644 src/test/ui/issues/issue-28950.rs create mode 100644 src/test/ui/issues/issue-28983.rs create mode 100644 src/test/ui/issues/issue-29053.rs create mode 100644 src/test/ui/issues/issue-29071-2.rs create mode 100644 src/test/ui/issues/issue-29092.rs create mode 100644 src/test/ui/issues/issue-29166.rs create mode 100644 src/test/ui/issues/issue-29227.rs create mode 100644 src/test/ui/issues/issue-2935.rs create mode 100644 src/test/ui/issues/issue-2936.rs create mode 100644 src/test/ui/issues/issue-29466.rs create mode 100644 src/test/ui/issues/issue-29485.rs create mode 100644 src/test/ui/issues/issue-29488.rs create mode 100644 src/test/ui/issues/issue-29522.rs create mode 100644 src/test/ui/issues/issue-29663.rs create mode 100644 src/test/ui/issues/issue-29668.rs create mode 100644 src/test/ui/issues/issue-29746.rs create mode 100644 src/test/ui/issues/issue-29844.rs create mode 100644 src/test/ui/issues/issue-2989.rs create mode 100644 src/test/ui/issues/issue-29914-2.rs create mode 100644 src/test/ui/issues/issue-29914-3.rs create mode 100644 src/test/ui/issues/issue-29914.rs create mode 100644 src/test/ui/issues/issue-29927-1.rs create mode 100644 src/test/ui/issues/issue-29927.rs create mode 100644 src/test/ui/issues/issue-29948.rs create mode 100644 src/test/ui/issues/issue-30018-nopanic.rs create mode 100644 src/test/ui/issues/issue-30018-panic.rs create mode 100644 src/test/ui/issues/issue-30081.rs create mode 100644 src/test/ui/issues/issue-3012-2.rs create mode 100644 src/test/ui/issues/issue-3026.rs create mode 100644 src/test/ui/issues/issue-3037.rs create mode 100644 src/test/ui/issues/issue-30371.rs create mode 100644 src/test/ui/issues/issue-30490.rs create mode 100644 src/test/ui/issues/issue-3052.rs create mode 100644 src/test/ui/issues/issue-30530.rs create mode 100644 src/test/ui/issues/issue-30615.rs create mode 100644 src/test/ui/issues/issue-30756.rs create mode 100644 src/test/ui/issues/issue-30891.rs create mode 100644 src/test/ui/issues/issue-3091.rs create mode 100644 src/test/ui/issues/issue-3109.rs create mode 100644 src/test/ui/issues/issue-3121.rs create mode 100644 src/test/ui/issues/issue-31267-additional.rs create mode 100644 src/test/ui/issues/issue-31267.rs create mode 100644 src/test/ui/issues/issue-31299.rs create mode 100644 src/test/ui/issues/issue-3136-b.rs create mode 100644 src/test/ui/issues/issue-31702.rs create mode 100644 src/test/ui/issues/issue-31776.rs create mode 100644 src/test/ui/issues/issue-32008.rs create mode 100644 src/test/ui/issues/issue-3211.rs create mode 100644 src/test/ui/issues/issue-3220.rs create mode 100644 src/test/ui/issues/issue-32292.rs create mode 100644 src/test/ui/issues/issue-32389.rs create mode 100644 src/test/ui/issues/issue-32518.rs create mode 100644 src/test/ui/issues/issue-32805.rs create mode 100644 src/test/ui/issues/issue-3290.rs create mode 100644 src/test/ui/issues/issue-32947.rs create mode 100644 src/test/ui/issues/issue-33096.rs create mode 100644 src/test/ui/issues/issue-33185.rs create mode 100644 src/test/ui/issues/issue-33187.rs create mode 100644 src/test/ui/issues/issue-33202.rs create mode 100644 src/test/ui/issues/issue-333.rs create mode 100644 src/test/ui/issues/issue-33387.rs create mode 100644 src/test/ui/issues/issue-33461.rs create mode 100644 src/test/ui/issues/issue-33498.rs create mode 100644 src/test/ui/issues/issue-33537.rs create mode 100644 src/test/ui/issues/issue-33687.rs create mode 100644 src/test/ui/issues/issue-33770.rs create mode 100644 src/test/ui/issues/issue-3389.rs create mode 100644 src/test/ui/issues/issue-33992.rs create mode 100644 src/test/ui/issues/issue-34053.rs create mode 100644 src/test/ui/issues/issue-34074.rs create mode 100644 src/test/ui/issues/issue-3429.rs create mode 100644 src/test/ui/issues/issue-34427.rs create mode 100644 src/test/ui/issues/issue-3447.rs create mode 100644 src/test/ui/issues/issue-34503.rs create mode 100644 src/test/ui/issues/issue-34569.rs create mode 100644 src/test/ui/issues/issue-34571.rs create mode 100644 src/test/ui/issues/issue-34784.rs create mode 100644 src/test/ui/issues/issue-34796.rs create mode 100644 src/test/ui/issues/issue-34798.rs create mode 100644 src/test/ui/issues/issue-34932.rs create mode 100644 src/test/ui/issues/issue-3500.rs create mode 100644 src/test/ui/issues/issue-35423.rs create mode 100644 src/test/ui/issues/issue-3556.rs create mode 100644 src/test/ui/issues/issue-3559.rs create mode 100644 src/test/ui/issues/issue-35600.rs create mode 100644 src/test/ui/issues/issue-3563-3.rs create mode 100644 src/test/ui/issues/issue-3574.rs create mode 100644 src/test/ui/issues/issue-35815.rs create mode 100644 src/test/ui/issues/issue-36023.rs create mode 100644 src/test/ui/issues/issue-36036-associated-type-layout.rs create mode 100644 src/test/ui/issues/issue-36053.rs create mode 100644 src/test/ui/issues/issue-36139-normalize-closure-sig.rs create mode 100644 src/test/ui/issues/issue-36260.rs create mode 100644 src/test/ui/issues/issue-36278-prefix-nesting.rs create mode 100644 src/test/ui/issues/issue-36381.rs create mode 100644 src/test/ui/issues/issue-36401.rs create mode 100644 src/test/ui/issues/issue-36474.rs create mode 100644 src/test/ui/issues/issue-3656.rs create mode 100644 src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs create mode 100644 src/test/ui/issues/issue-36768.rs create mode 100644 src/test/ui/issues/issue-36786-resolve-call.rs create mode 100644 src/test/ui/issues/issue-36792.rs create mode 100644 src/test/ui/issues/issue-36816.rs create mode 100644 src/test/ui/issues/issue-3683.rs create mode 100644 src/test/ui/issues/issue-36856.rs create mode 100644 src/test/ui/issues/issue-36936.rs create mode 100644 src/test/ui/issues/issue-36954.rs create mode 100644 src/test/ui/issues/issue-3702.rs create mode 100644 src/test/ui/issues/issue-37109.rs create mode 100644 src/test/ui/issues/issue-37175.rs create mode 100644 src/test/ui/issues/issue-37222.rs create mode 100644 src/test/ui/issues/issue-37291/auxiliary/lib.rs create mode 100644 src/test/ui/issues/issue-37291/main.rs create mode 100644 src/test/ui/issues/issue-3743.rs create mode 100644 src/test/ui/issues/issue-3753.rs create mode 100644 src/test/ui/issues/issue-37686.rs create mode 100644 src/test/ui/issues/issue-3794.rs create mode 100644 src/test/ui/issues/issue-37991.rs create mode 100644 src/test/ui/issues/issue-38002.rs create mode 100644 src/test/ui/issues/issue-38033.rs create mode 100644 src/test/ui/issues/issue-38074.rs create mode 100644 src/test/ui/issues/issue-38091.rs create mode 100644 src/test/ui/issues/issue-38190.rs create mode 100644 src/test/ui/issues/issue-38226.rs create mode 100644 src/test/ui/issues/issue-38437.rs create mode 100644 src/test/ui/issues/issue-3847.rs create mode 100644 src/test/ui/issues/issue-38556.rs create mode 100644 src/test/ui/issues/issue-38763.rs create mode 100644 src/test/ui/issues/issue-3878.rs create mode 100644 src/test/ui/issues/issue-38942.rs create mode 100644 src/test/ui/issues/issue-3895.rs create mode 100644 src/test/ui/issues/issue-38987.rs create mode 100644 src/test/ui/issues/issue-3904.rs create mode 100644 src/test/ui/issues/issue-39292.rs create mode 100644 src/test/ui/issues/issue-3935.rs create mode 100644 src/test/ui/issues/issue-39367.rs create mode 100644 src/test/ui/issues/issue-39548.rs create mode 100644 src/test/ui/issues/issue-39709.rs create mode 100644 src/test/ui/issues/issue-39720.rs create mode 100644 src/test/ui/issues/issue-39720.stderr create mode 100644 src/test/ui/issues/issue-3979-generics.rs create mode 100644 src/test/ui/issues/issue-3979-xcrate.rs create mode 100644 src/test/ui/issues/issue-3979.rs create mode 100644 src/test/ui/issues/issue-39808.rs create mode 100644 src/test/ui/issues/issue-39823.rs create mode 100644 src/test/ui/issues/issue-39827.rs create mode 100644 src/test/ui/issues/issue-40003.rs create mode 100644 src/test/ui/issues/issue-40085.rs create mode 100644 src/test/ui/issues/issue-40235.rs create mode 100644 src/test/ui/issues/issue-40408.rs create mode 100644 src/test/ui/issues/issue-40469.rs create mode 100644 src/test/ui/issues/issue-40770.rs create mode 100644 src/test/ui/issues/issue-40847.rs create mode 100644 src/test/ui/issues/issue-40883.rs create mode 100644 src/test/ui/issues/issue-40951.rs create mode 100644 src/test/ui/issues/issue-41053.rs create mode 100644 src/test/ui/issues/issue-4107.rs create mode 100644 src/test/ui/issues/issue-41213.rs create mode 100644 src/test/ui/issues/issue-41479.rs create mode 100644 src/test/ui/issues/issue-41498.rs create mode 100644 src/test/ui/issues/issue-41604.rs create mode 100644 src/test/ui/issues/issue-41677.rs create mode 100644 src/test/ui/issues/issue-41696.rs create mode 100644 src/test/ui/issues/issue-41744.rs create mode 100644 src/test/ui/issues/issue-41803.rs create mode 100644 src/test/ui/issues/issue-41849-variance-req.rs create mode 100644 src/test/ui/issues/issue-41888.rs create mode 100644 src/test/ui/issues/issue-42007.rs create mode 100644 src/test/ui/issues/issue-4208.rs create mode 100644 src/test/ui/issues/issue-42148.rs create mode 100644 src/test/ui/issues/issue-42210.rs create mode 100644 src/test/ui/issues/issue-4228.rs create mode 100644 src/test/ui/issues/issue-42453.rs create mode 100644 src/test/ui/issues/issue-42463.rs create mode 100644 src/test/ui/issues/issue-4252.rs create mode 100644 src/test/ui/issues/issue-42552.rs create mode 100644 src/test/ui/issues/issue-42679.rs create mode 100644 src/test/ui/issues/issue-42747.rs create mode 100644 src/test/ui/issues/issue-43132.rs create mode 100644 src/test/ui/issues/issue-43205.rs create mode 100644 src/test/ui/issues/issue-43291.rs create mode 100644 src/test/ui/issues/issue-4333.rs create mode 100644 src/test/ui/issues/issue-43692.rs create mode 100644 src/test/ui/issues/issue-43853.rs create mode 100644 src/test/ui/issues/issue-4387.rs create mode 100644 src/test/ui/issues/issue-43910.rs create mode 100644 src/test/ui/issues/issue-43923.rs create mode 100644 src/test/ui/issues/issue-4401.rs create mode 100644 src/test/ui/issues/issue-44333.rs create mode 100644 src/test/ui/issues/issue-4446.rs create mode 100644 src/test/ui/issues/issue-4448.rs create mode 100644 src/test/ui/issues/issue-45124.rs create mode 100644 src/test/ui/issues/issue-45152.rs create mode 100644 src/test/ui/issues/issue-4541.rs create mode 100644 src/test/ui/issues/issue-4542.rs create mode 100644 src/test/ui/issues/issue-4545.rs create mode 100644 src/test/ui/issues/issue-45510.rs create mode 100644 src/test/ui/issues/issue-45731.rs create mode 100644 src/test/ui/issues/issue-46069.rs create mode 100644 src/test/ui/issues/issue-46095.rs create mode 100644 src/test/ui/issues/issue-46519.rs create mode 100644 src/test/ui/issues/issue-46553.rs create mode 100644 src/test/ui/issues/issue-46845.rs create mode 100644 src/test/ui/issues/issue-46855.rs create mode 100644 src/test/ui/issues/issue-46920-byte-array-patterns.rs create mode 100644 src/test/ui/issues/issue-47139-1.rs create mode 100644 src/test/ui/issues/issue-47139-2.rs create mode 100644 src/test/ui/issues/issue-4734.rs create mode 100644 src/test/ui/issues/issue-4735.rs create mode 100644 src/test/ui/issues/issue-47364.rs create mode 100644 src/test/ui/issues/issue-4759-1.rs create mode 100644 src/test/ui/issues/issue-4759.rs create mode 100644 src/test/ui/issues/issue-47638.rs create mode 100644 src/test/ui/issues/issue-48006.rs create mode 100644 src/test/ui/issues/issue-48159.rs create mode 100644 src/test/ui/issues/issue-48508-aux.rs create mode 100644 src/test/ui/issues/issue-48508.rs create mode 100644 src/test/ui/issues/issue-4865-1.rs create mode 100644 src/test/ui/issues/issue-4865-2.rs create mode 100644 src/test/ui/issues/issue-4865-3.rs create mode 100644 src/test/ui/issues/issue-4875.rs create mode 100644 src/test/ui/issues/issue-48962.rs create mode 100644 src/test/ui/issues/issue-48984.rs create mode 100644 src/test/ui/issues/issue-49298.rs create mode 100644 src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs create mode 100644 src/test/ui/issues/issue-49632.rs create mode 100644 src/test/ui/issues/issue-49685.rs create mode 100644 src/test/ui/issues/issue-49854.rs create mode 100644 src/test/ui/issues/issue-49955-2.rs create mode 100644 src/test/ui/issues/issue-49955.rs create mode 100644 src/test/ui/issues/issue-49973.rs create mode 100644 src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs create mode 100644 src/test/ui/issues/issue-50415.rs create mode 100644 src/test/ui/issues/issue-50442.rs create mode 100644 src/test/ui/issues/issue-5060.rs create mode 100644 src/test/ui/issues/issue-50689.rs create mode 100644 src/test/ui/issues/issue-50731.rs create mode 100644 src/test/ui/issues/issue-50811.rs create mode 100644 src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs create mode 100644 src/test/ui/issues/issue-50865-private-impl-trait/main.rs create mode 100644 src/test/ui/issues/issue-51185.rs create mode 100644 src/test/ui/issues/issue-51345.rs create mode 100644 src/test/ui/issues/issue-51582.rs create mode 100644 src/test/ui/issues/issue-51907.rs create mode 100644 src/test/ui/issues/issue-5192.rs create mode 100644 src/test/ui/issues/issue-52140/auxiliary/some_crate.rs create mode 100644 src/test/ui/issues/issue-52140/main.rs create mode 100644 src/test/ui/issues/issue-52141/auxiliary/some_crate.rs create mode 100644 src/test/ui/issues/issue-52141/main.rs create mode 100644 src/test/ui/issues/issue-52169.rs create mode 100644 src/test/ui/issues/issue-5239-2.rs create mode 100644 src/test/ui/issues/issue-5243.rs create mode 100644 src/test/ui/issues/issue-52557.rs create mode 100644 src/test/ui/issues/issue-52705/auxiliary/png2.rs create mode 100644 src/test/ui/issues/issue-52705/main.rs create mode 100644 src/test/ui/issues/issue-5280.rs create mode 100644 src/test/ui/issues/issue-5315.rs create mode 100644 src/test/ui/issues/issue-5321-immediates-with-bare-self.rs create mode 100644 src/test/ui/issues/issue-53333.rs create mode 100644 src/test/ui/issues/issue-53728.rs create mode 100644 src/test/ui/issues/issue-53843.rs create mode 100644 src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs create mode 100644 src/test/ui/issues/issue-54467.rs create mode 100644 src/test/ui/issues/issue-54477-reduced-2.rs create mode 100644 src/test/ui/issues/issue-54696.rs create mode 100644 src/test/ui/issues/issue-5518.rs create mode 100644 src/test/ui/issues/issue-5521.rs create mode 100644 src/test/ui/issues/issue-5530.rs create mode 100644 src/test/ui/issues/issue-55376.rs create mode 100644 src/test/ui/issues/issue-55380.rs create mode 100644 src/test/ui/issues/issue-5550.rs create mode 100644 src/test/ui/issues/issue-5554.rs create mode 100644 src/test/ui/issues/issue-56237.rs create mode 100644 src/test/ui/issues/issue-5666.rs create mode 100644 src/test/ui/issues/issue-5688.rs create mode 100644 src/test/ui/issues/issue-5708.rs create mode 100644 src/test/ui/issues/issue-5718.rs create mode 100644 src/test/ui/issues/issue-5741.rs create mode 100644 src/test/ui/issues/issue-5791.rs create mode 100644 src/test/ui/issues/issue-58212.rs create mode 100644 src/test/ui/issues/issue-58435-ice-with-assoc-const.rs create mode 100644 src/test/ui/issues/issue-58463.rs create mode 100644 src/test/ui/issues/issue-5917.rs create mode 100644 src/test/ui/issues/issue-5988.rs create mode 100644 src/test/ui/issues/issue-5997.rs create mode 100644 src/test/ui/issues/issue-6117.rs create mode 100644 src/test/ui/issues/issue-6128.rs create mode 100644 src/test/ui/issues/issue-6130.rs create mode 100644 src/test/ui/issues/issue-6153.rs create mode 100644 src/test/ui/issues/issue-6157.rs create mode 100644 src/test/ui/issues/issue-61696.rs create mode 100644 src/test/ui/issues/issue-61894.rs create mode 100644 src/test/ui/issues/issue-6318.rs create mode 100644 src/test/ui/issues/issue-6334.rs create mode 100644 src/test/ui/issues/issue-6344-let.rs create mode 100644 src/test/ui/issues/issue-6344-match.rs create mode 100644 src/test/ui/issues/issue-6449.rs create mode 100644 src/test/ui/issues/issue-6892.rs create mode 100644 src/test/ui/issues/issue-6919.rs create mode 100644 src/test/ui/issues/issue-7012.rs create mode 100644 src/test/ui/issues/issue-7178.rs create mode 100644 src/test/ui/issues/issue-7222.rs create mode 100644 src/test/ui/issues/issue-7344.rs create mode 100644 src/test/ui/issues/issue-7519-match-unit-in-arg.rs create mode 100644 src/test/ui/issues/issue-7563.rs create mode 100644 src/test/ui/issues/issue-7575.rs create mode 100644 src/test/ui/issues/issue-7660.rs create mode 100644 src/test/ui/issues/issue-7663.rs create mode 100644 src/test/ui/issues/issue-7784.rs create mode 100644 src/test/ui/issues/issue-7899.rs create mode 100644 src/test/ui/issues/issue-7911.rs create mode 100644 src/test/ui/issues/issue-8044.rs create mode 100644 src/test/ui/issues/issue-8248.rs create mode 100644 src/test/ui/issues/issue-8249.rs create mode 100644 src/test/ui/issues/issue-8259.rs create mode 100644 src/test/ui/issues/issue-8351-1.rs create mode 100644 src/test/ui/issues/issue-8351-2.rs create mode 100644 src/test/ui/issues/issue-8391.rs create mode 100644 src/test/ui/issues/issue-8401.rs create mode 100644 src/test/ui/issues/issue-8460.rs create mode 100644 src/test/ui/issues/issue-8498.rs create mode 100644 src/test/ui/issues/issue-8506.rs create mode 100644 src/test/ui/issues/issue-868.rs create mode 100644 src/test/ui/issues/issue-8709.rs create mode 100644 src/test/ui/issues/issue-8783.rs create mode 100644 src/test/ui/issues/issue-8827.rs create mode 100644 src/test/ui/issues/issue-8851.rs create mode 100644 src/test/ui/issues/issue-8860.rs create mode 100644 src/test/ui/issues/issue-8898.rs create mode 100644 src/test/ui/issues/issue-9047.rs create mode 100644 src/test/ui/issues/issue-9123.rs create mode 100644 src/test/ui/issues/issue-9129.rs create mode 100644 src/test/ui/issues/issue-9155.rs create mode 100644 src/test/ui/issues/issue-9188.rs create mode 100644 src/test/ui/issues/issue-9259.rs create mode 100644 src/test/ui/issues/issue-9382.rs create mode 100644 src/test/ui/issues/issue-9394-inherited-trait-calls.rs create mode 100644 src/test/ui/issues/issue-9396.rs create mode 100644 src/test/ui/issues/issue-9446.rs create mode 100644 src/test/ui/issues/issue-9737.rs create mode 100644 src/test/ui/issues/issue-979.rs create mode 100644 src/test/ui/issues/issue-9837.rs create mode 100644 src/test/ui/issues/issue-9906.rs create mode 100644 src/test/ui/issues/issue-9918.rs create mode 100644 src/test/ui/issues/issue-9942.rs create mode 100644 src/test/ui/issues/issue-9951.rs create mode 100644 src/test/ui/issues/issue-9968.rs create mode 100644 src/test/ui/istr.rs create mode 100644 src/test/ui/item-name-overload.rs create mode 100644 src/test/ui/iterators/into-iterator-type-inference-shift.rs create mode 100644 src/test/ui/iterators/iter-cloned-type-inference.rs create mode 100644 src/test/ui/iterators/iter-range.rs create mode 100644 src/test/ui/iterators/iter-step-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-step-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs create mode 100644 src/test/ui/iterators/iter-zip.rs create mode 100644 src/test/ui/keyword-changes-2012-07-31.rs create mode 100644 src/test/ui/kindck-implicit-close-over-mut-var.rs create mode 100644 src/test/ui/kinds-in-metadata.rs create mode 100644 src/test/ui/lambda-infer-unresolved.rs create mode 100644 src/test/ui/lambda-var-hygiene.rs create mode 100644 src/test/ui/large-records.rs create mode 100644 src/test/ui/last-use-in-block.rs create mode 100644 src/test/ui/last-use-in-cap-clause.rs create mode 100644 src/test/ui/last-use-is-capture.rs create mode 100644 src/test/ui/lazy-and-or.rs create mode 100644 src/test/ui/lazy-init.rs create mode 100644 src/test/ui/leak-unique-as-tydesc.rs create mode 100644 src/test/ui/lex-bare-cr-nondoc-comment.rs create mode 100644 src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs create mode 100644 src/test/ui/lexical-scoping.rs create mode 100644 src/test/ui/lib-defaults.rs create mode 100644 src/test/ui/link-cfg-works.rs create mode 100644 src/test/ui/link-section.rs create mode 100644 src/test/ui/linkage1.rs create mode 100644 src/test/ui/lint-cap.rs create mode 100644 src/test/ui/lint-dead-code-associated-type.rs create mode 100644 src/test/ui/lint-dead-code-variant.rs create mode 100644 src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs create mode 100644 src/test/ui/lint-unknown-lints-at-crate-level.rs create mode 100644 src/test/ui/list.rs create mode 100644 src/test/ui/liveness-assign-imm-local-after-ret.rs create mode 100644 src/test/ui/llvm-pr32379.rs create mode 100644 src/test/ui/log-err-phi.rs create mode 100644 src/test/ui/log-knows-the-names-of-variants-in-std.rs create mode 100644 src/test/ui/log-knows-the-names-of-variants.rs create mode 100644 src/test/ui/log-poly.rs create mode 100644 src/test/ui/logging-only-prints-once.rs create mode 100644 src/test/ui/logging_before_rt_started.rs create mode 100644 src/test/ui/long-while.rs create mode 100644 src/test/ui/lto-many-codegen-units.rs create mode 100644 src/test/ui/lto-still-runs-thread-dtors.rs create mode 100644 src/test/ui/lub-glb-with-unbound-infer-var.rs create mode 100644 src/test/ui/macro-quote-cond.rs create mode 100644 src/test/ui/macro-quote-test.rs create mode 100644 src/test/ui/macros/assert-eq-macro-success.rs create mode 100644 src/test/ui/macros/assert-eq-macro-unsized.rs create mode 100644 src/test/ui/macros/assert-ne-macro-success.rs create mode 100644 src/test/ui/macros/assert-ne-macro-unsized.rs create mode 100644 src/test/ui/macros/auxiliary/macro-comma-support.rs create mode 100644 src/test/ui/macros/auxiliary/macro-include-items-expr.rs create mode 100644 src/test/ui/macros/auxiliary/macro-include-items-item.rs create mode 100644 src/test/ui/macros/auxiliary/macro_crate_def_only.rs create mode 100644 src/test/ui/macros/auxiliary/macro_export_inner_module.rs create mode 100644 src/test/ui/macros/auxiliary/macro_with_super_1.rs create mode 100644 src/test/ui/macros/auxiliary/two_macros-rpass.rs create mode 100644 src/test/ui/macros/auxiliary/use-macro-self.rs create mode 100644 src/test/ui/macros/colorful-write-macros.rs create mode 100644 src/test/ui/macros/conditional-debug-macro-on.rs create mode 100644 src/test/ui/macros/die-macro.rs create mode 100644 src/test/ui/macros/issue-25274.rs create mode 100644 src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs create mode 100644 src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout create mode 100644 src/test/ui/macros/macro-2.rs create mode 100644 src/test/ui/macros/macro-as-fn-body.rs create mode 100644 src/test/ui/macros/macro-attribute-expansion.rs create mode 100644 src/test/ui/macros/macro-attributes.rs create mode 100644 src/test/ui/macros/macro-block-nonterminal.rs create mode 100644 src/test/ui/macros/macro-crate-def-only.rs create mode 100644 src/test/ui/macros/macro-crate-nonterminal-renamed.rs create mode 100644 src/test/ui/macros/macro-crate-nonterminal.rs create mode 100644 src/test/ui/macros/macro-crate-use.rs create mode 100644 src/test/ui/macros/macro-deep_expansion.rs create mode 100644 src/test/ui/macros/macro-delimiter-significance.rs create mode 100644 src/test/ui/macros/macro-doc-comments.rs create mode 100644 src/test/ui/macros/macro-doc-escapes.rs create mode 100644 src/test/ui/macros/macro-doc-raw-str-hashes.rs create mode 100644 src/test/ui/macros/macro-export-inner-module.rs create mode 100644 src/test/ui/macros/macro-first-set.rs create mode 100644 src/test/ui/macros/macro-followed-by-seq.rs create mode 100644 src/test/ui/macros/macro-include-items.rs create mode 100644 src/test/ui/macros/macro-interpolation.rs create mode 100644 src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs create mode 100644 src/test/ui/macros/macro-lifetime-used-with-bound.rs create mode 100644 src/test/ui/macros/macro-lifetime-used-with-labels.rs create mode 100644 src/test/ui/macros/macro-lifetime-used-with-labels.stderr create mode 100644 src/test/ui/macros/macro-lifetime-used-with-static.rs create mode 100644 src/test/ui/macros/macro-lifetime.rs create mode 100644 src/test/ui/macros/macro-literal.rs create mode 100644 src/test/ui/macros/macro-meta-items.rs create mode 100644 src/test/ui/macros/macro-method-issue-4621.rs create mode 100644 src/test/ui/macros/macro-multiple-items.rs create mode 100644 src/test/ui/macros/macro-named-default.rs create mode 100644 src/test/ui/macros/macro-nested_definition_issue-31946.rs create mode 100644 src/test/ui/macros/macro-nested_expr.rs create mode 100644 src/test/ui/macros/macro-nested_stmt_macros.rs create mode 100644 src/test/ui/macros/macro-nt-list.rs create mode 100644 src/test/ui/macros/macro-of-higher-order.rs create mode 100644 src/test/ui/macros/macro-pat-follow.rs create mode 100644 src/test/ui/macros/macro-pat-neg-lit.rs create mode 100644 src/test/ui/macros/macro-pat.rs create mode 100644 src/test/ui/macros/macro-path.rs create mode 100644 src/test/ui/macros/macro-pub-matcher.rs create mode 100644 src/test/ui/macros/macro-seq-followed-by-seq.rs create mode 100644 src/test/ui/macros/macro-stmt.rs create mode 100644 src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs create mode 100644 src/test/ui/macros/macro-tt-followed-by-seq.rs create mode 100644 src/test/ui/macros/macro-use-all-and-none.rs create mode 100644 src/test/ui/macros/macro-use-all-and-none.stderr create mode 100644 src/test/ui/macros/macro-use-all.rs create mode 100644 src/test/ui/macros/macro-use-both.rs create mode 100644 src/test/ui/macros/macro-use-one.rs create mode 100644 src/test/ui/macros/macro-with-attrs1.rs create mode 100644 src/test/ui/macros/macro-with-attrs2.rs create mode 100644 src/test/ui/macros/macro-with-braces-in-expr-position.rs create mode 100644 src/test/ui/macros/macro_with_super_2.rs create mode 100644 src/test/ui/macros/meta-variable-misuse.rs create mode 100644 src/test/ui/macros/parse-complex-macro-invoc-op.rs create mode 100644 src/test/ui/macros/paths-in-macro-invocations.rs create mode 100644 src/test/ui/macros/pub-item-inside-macro.rs create mode 100644 src/test/ui/macros/pub-method-inside-macro.rs create mode 100644 src/test/ui/macros/semi-after-macro-ty.rs create mode 100644 src/test/ui/macros/stmt_expr_attr_macro_parse.rs create mode 100644 src/test/ui/macros/syntax-extension-cfg.rs create mode 100644 src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment create mode 100644 src/test/ui/macros/syntax-extension-source-utils.rs create mode 100644 src/test/ui/macros/try-macro.rs create mode 100644 src/test/ui/macros/two-macro-use.rs create mode 100644 src/test/ui/macros/type-macros-hlist.rs create mode 100644 src/test/ui/macros/type-macros-simple.rs create mode 100644 src/test/ui/macros/typeck-macro-interaction-issue-8852.rs create mode 100644 src/test/ui/macros/use-macro-self.rs create mode 100644 src/test/ui/max-min-classes.rs create mode 100644 src/test/ui/methods/auxiliary/method_self_arg1.rs create mode 100644 src/test/ui/methods/auxiliary/method_self_arg2.rs create mode 100644 src/test/ui/methods/method-argument-inference-associated-type.rs create mode 100644 src/test/ui/methods/method-early-bound-lifetimes-on-self.rs create mode 100644 src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs create mode 100644 src/test/ui/methods/method-normalize-bounds-issue-20604.rs create mode 100644 src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs create mode 100644 src/test/ui/methods/method-projection.rs create mode 100644 src/test/ui/methods/method-recursive-blanket-impl.rs create mode 100644 src/test/ui/methods/method-self-arg-aux1.rs create mode 100644 src/test/ui/methods/method-self-arg-aux2.rs create mode 100644 src/test/ui/methods/method-self-arg-trait.rs create mode 100644 src/test/ui/methods/method-self-arg.rs create mode 100644 src/test/ui/methods/method-two-trait-defer-resolution-1.rs create mode 100644 src/test/ui/methods/method-two-trait-defer-resolution-2.rs create mode 100644 src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs create mode 100644 src/test/ui/methods/method-where-clause.rs create mode 100644 src/test/ui/mid-path-type-params.rs create mode 100644 src/test/ui/minmax-stability-issue-23687.rs create mode 100644 src/test/ui/mir/auxiliary/mir_external_refs.rs create mode 100644 src/test/ui/mir/mir-inlining/ice-issue-45493.rs create mode 100644 src/test/ui/mir/mir-inlining/ice-issue-45885.rs create mode 100644 src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs create mode 100644 src/test/ui/mir/mir-typeck-normalize-fn-sig.rs create mode 100644 src/test/ui/mir/mir_adt_construction.rs create mode 100644 src/test/ui/mir/mir_ascription_coercion.rs create mode 100644 src/test/ui/mir/mir_augmented_assignments.rs create mode 100644 src/test/ui/mir/mir_autoderef.rs create mode 100644 src/test/ui/mir/mir_boxing.rs create mode 100644 src/test/ui/mir/mir_build_match_comparisons.rs create mode 100644 src/test/ui/mir/mir_call_with_associated_type.rs create mode 100644 src/test/ui/mir/mir_calls_to_shims.rs create mode 100644 src/test/ui/mir/mir_cast_fn_ret.rs create mode 100644 src/test/ui/mir/mir_codegen_array.rs create mode 100644 src/test/ui/mir/mir_codegen_array_2.rs create mode 100644 src/test/ui/mir/mir_codegen_call_converging.rs create mode 100644 src/test/ui/mir/mir_codegen_calls.rs create mode 100644 src/test/ui/mir/mir_codegen_calls_variadic.rs create mode 100644 src/test/ui/mir/mir_codegen_critical_edge.rs create mode 100644 src/test/ui/mir/mir_codegen_spike1.rs create mode 100644 src/test/ui/mir/mir_codegen_switch.rs create mode 100644 src/test/ui/mir/mir_codegen_switchint.rs create mode 100644 src/test/ui/mir/mir_coercion_casts.rs create mode 100644 src/test/ui/mir/mir_coercions.rs create mode 100644 src/test/ui/mir/mir_constval_adts.rs create mode 100644 src/test/ui/mir/mir_drop_order.rs create mode 100644 src/test/ui/mir/mir_early_return_scope.rs create mode 100644 src/test/ui/mir/mir_fat_ptr.rs create mode 100644 src/test/ui/mir/mir_fat_ptr_drop.rs create mode 100644 src/test/ui/mir/mir_heavy_promoted.rs create mode 100644 src/test/ui/mir/mir_match_arm_guard.rs create mode 100644 src/test/ui/mir/mir_match_test.rs create mode 100644 src/test/ui/mir/mir_misc_casts.rs create mode 100644 src/test/ui/mir/mir_overflow_off.rs create mode 100644 src/test/ui/mir/mir_raw_fat_ptr.rs create mode 100644 src/test/ui/mir/mir_refs_correct.rs create mode 100644 src/test/ui/mir/mir_small_agg_arg.rs create mode 100644 src/test/ui/mir/mir_static_subtype.rs create mode 100644 src/test/ui/mir/mir_struct_with_assoc_ty.rs create mode 100644 src/test/ui/mir/mir_temp_promotions.rs create mode 100644 src/test/ui/mir/mir_void_return.rs create mode 100644 src/test/ui/mir/mir_void_return_2.rs create mode 100644 src/test/ui/modules/auxiliary/two_macros_2.rs create mode 100644 src/test/ui/modules/mod-inside-fn.rs create mode 100644 src/test/ui/modules/mod-view-items.rs create mode 100644 src/test/ui/modules/mod_dir_implicit.rs create mode 100644 src/test/ui/modules/mod_dir_implicit_aux/compiletest-ignore-dir create mode 100644 src/test/ui/modules/mod_dir_implicit_aux/mod.rs create mode 100644 src/test/ui/modules/mod_dir_path.rs create mode 100644 src/test/ui/modules/mod_dir_path2.rs create mode 100644 src/test/ui/modules/mod_dir_path3.rs create mode 100644 src/test/ui/modules/mod_dir_path_multi.rs create mode 100644 src/test/ui/modules/mod_dir_recursive.rs create mode 100644 src/test/ui/modules/mod_dir_simple.rs create mode 100644 src/test/ui/modules/mod_dir_simple/compiletest-ignore-dir create mode 100644 src/test/ui/modules/mod_dir_simple/load_another_mod.rs create mode 100644 src/test/ui/modules/mod_dir_simple/test.rs create mode 100644 src/test/ui/modules/mod_file.rs create mode 100644 src/test/ui/modules/mod_file_aux.rs create mode 100644 src/test/ui/modules/mod_file_with_path_attr.rs create mode 100644 src/test/ui/modules/module-polymorphism3-files/compiletest-ignore-dir create mode 100644 src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs create mode 100644 src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs create mode 100644 src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs create mode 100644 src/test/ui/monad.rs create mode 100644 src/test/ui/monomorphize-abi-alignment.rs create mode 100644 src/test/ui/monomorphized-callees-with-ty-params-3314.rs create mode 100644 src/test/ui/moves/move-1-unique.rs create mode 100644 src/test/ui/moves/move-2-unique.rs create mode 100644 src/test/ui/moves/move-2.rs create mode 100644 src/test/ui/moves/move-3-unique.rs create mode 100644 src/test/ui/moves/move-4-unique.rs create mode 100644 src/test/ui/moves/move-4.rs create mode 100644 src/test/ui/moves/move-arg-2-unique.rs create mode 100644 src/test/ui/moves/move-arg-2.rs create mode 100644 src/test/ui/moves/move-arg.rs create mode 100644 src/test/ui/moves/move-nullary-fn.rs create mode 100644 src/test/ui/moves/move-out-of-field.rs create mode 100644 src/test/ui/moves/move-scalar.rs create mode 100644 src/test/ui/moves/moves-based-on-type-capture-clause.rs create mode 100644 src/test/ui/mpsc_stress.rs create mode 100644 src/test/ui/msvc-data-only.rs create mode 100644 src/test/ui/multi-panic.rs create mode 100644 src/test/ui/multibyte.rs create mode 100644 src/test/ui/multidispatch-conditional-impl-not-considered.rs create mode 100644 src/test/ui/multidispatch1.rs create mode 100644 src/test/ui/multidispatch2.rs create mode 100644 src/test/ui/multiline-comment.rs create mode 100644 src/test/ui/multiple-reprs.rs create mode 100644 src/test/ui/mut-function-arguments.rs create mode 100644 src/test/ui/mut-vstore-expr.rs create mode 100644 src/test/ui/mutual-recursion-group.rs create mode 100644 src/test/ui/native-print-no-runtime.rs create mode 100644 src/test/ui/negative.rs create mode 100644 src/test/ui/nested-block-comment.rs create mode 100644 src/test/ui/nested-class.rs create mode 100644 src/test/ui/nested-function-names-issue-8587.rs create mode 100644 src/test/ui/nested_item_main.rs create mode 100644 src/test/ui/never-result.rs create mode 100644 src/test/ui/never-type-rvalues.rs create mode 100644 src/test/ui/never_coercions.rs create mode 100644 src/test/ui/new-box-syntax.rs create mode 100644 src/test/ui/new-box.rs create mode 100644 src/test/ui/new-impl-syntax.rs create mode 100644 src/test/ui/new-import-syntax.rs create mode 100644 src/test/ui/new-style-constants.rs create mode 100644 src/test/ui/new-unicode-escapes.rs create mode 100644 src/test/ui/new-unsafe-pointers.rs create mode 100644 src/test/ui/newlambdas-ret-infer.rs create mode 100644 src/test/ui/newlambdas-ret-infer2.rs create mode 100644 src/test/ui/newlambdas.rs create mode 100644 src/test/ui/newtype-polymorphic.rs create mode 100644 src/test/ui/newtype-temporary.rs create mode 100644 src/test/ui/newtype.rs create mode 100644 src/test/ui/nil-decl-in-foreign.rs create mode 100644 src/test/ui/nll/issue-47153-generic-const.rs create mode 100644 src/test/ui/nll/issue-47589.rs create mode 100644 src/test/ui/nll/issue-48623-closure.rs create mode 100644 src/test/ui/nll/issue-48623-generator.rs create mode 100644 src/test/ui/nll/issue-50343.rs create mode 100644 src/test/ui/nll/issue-50461-used-mut-from-moves.rs create mode 100644 src/test/ui/nll/issue-53123-raw-pointer-cast.rs create mode 100644 src/test/ui/nll/mutating_references.rs create mode 100644 src/test/ui/nll/process_or_insert_default.rs create mode 100644 src/test/ui/nll/rc-loop.rs create mode 100644 src/test/ui/no-core-1.rs create mode 100644 src/test/ui/no-core-2.rs create mode 100644 src/test/ui/no-landing-pads.rs create mode 100644 src/test/ui/no-std-1.rs create mode 100644 src/test/ui/no-std-2.rs create mode 100644 src/test/ui/no-std-3.rs create mode 100644 src/test/ui/no-stdio.rs create mode 100644 src/test/ui/non-built-in-quote.rs create mode 100644 src/test/ui/non-legacy-modes.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod/compiletest-ignore-dir create mode 100644 src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs create mode 100644 src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/compiletest-ignore-dir create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs create mode 100644 src/test/ui/non_modrs_mods/modrs_mod/mod.rs create mode 100644 src/test/ui/non_modrs_mods/non_modrs_mods.rs create mode 100644 src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs create mode 100644 src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir create mode 100644 src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs create mode 100644 src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs create mode 100644 src/test/ui/nul-characters.rs create mode 100644 src/test/ui/nullable-pointer-ffi-compat.rs create mode 100644 src/test/ui/nullable-pointer-iotareduction.rs create mode 100644 src/test/ui/nullable-pointer-size.rs create mode 100644 src/test/ui/numbers-arithmetic/arith-0.rs create mode 100644 src/test/ui/numbers-arithmetic/arith-1.rs create mode 100644 src/test/ui/numbers-arithmetic/arith-2.rs create mode 100644 src/test/ui/numbers-arithmetic/arith-unsigned.rs create mode 100644 src/test/ui/numbers-arithmetic/div-mod.rs create mode 100644 src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs create mode 100644 src/test/ui/numbers-arithmetic/float-literal-inference.rs create mode 100644 src/test/ui/numbers-arithmetic/float-nan.rs create mode 100644 src/test/ui/numbers-arithmetic/float-signature.rs create mode 100644 src/test/ui/numbers-arithmetic/float.rs create mode 100644 src/test/ui/numbers-arithmetic/float2.rs create mode 100644 src/test/ui/numbers-arithmetic/float_math.rs create mode 100644 src/test/ui/numbers-arithmetic/floatlits.rs create mode 100644 src/test/ui/numbers-arithmetic/i128-ffi.rs create mode 100644 src/test/ui/numbers-arithmetic/i128.rs create mode 100644 src/test/ui/numbers-arithmetic/i32-sub.rs create mode 100644 src/test/ui/numbers-arithmetic/i8-incr.rs create mode 100644 src/test/ui/numbers-arithmetic/int-abs-overflow.rs create mode 100644 src/test/ui/numbers-arithmetic/int.rs create mode 100644 src/test/ui/numbers-arithmetic/integer-literal-radix.rs create mode 100644 src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs create mode 100644 src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs create mode 100644 src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs create mode 100644 src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs create mode 100644 src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs create mode 100644 src/test/ui/numbers-arithmetic/num-wrapping.rs create mode 100644 src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs create mode 100644 src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs create mode 100644 src/test/ui/numbers-arithmetic/saturating-float-casts.rs create mode 100644 src/test/ui/numbers-arithmetic/shift-near-oflo.rs create mode 100644 src/test/ui/numbers-arithmetic/shift-various-types.rs create mode 100644 src/test/ui/numbers-arithmetic/shift.rs create mode 100644 src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs create mode 100644 src/test/ui/numbers-arithmetic/u128-as-f32.rs create mode 100644 src/test/ui/numbers-arithmetic/u128.rs create mode 100644 src/test/ui/numbers-arithmetic/u32-decr.rs create mode 100644 src/test/ui/numbers-arithmetic/u8-incr-decr.rs create mode 100644 src/test/ui/numbers-arithmetic/u8-incr.rs create mode 100644 src/test/ui/numbers-arithmetic/uint.rs create mode 100644 src/test/ui/object-lifetime-default-default-to-static.rs create mode 100644 src/test/ui/object-lifetime-default-from-rptr-box.rs create mode 100644 src/test/ui/object-lifetime-default-from-rptr-mut.rs create mode 100644 src/test/ui/object-lifetime-default-from-rptr.rs create mode 100644 src/test/ui/object-method-numbering.rs create mode 100644 src/test/ui/objects-coerce-freeze-borrored.rs create mode 100644 src/test/ui/objects-owned-object-borrowed-method-headerless.rs create mode 100644 src/test/ui/objects-owned-object-owned-method.rs create mode 100644 src/test/ui/once-move-out-on-heap.rs create mode 100644 src/test/ui/one-tuple.rs create mode 100644 src/test/ui/op-assign-builtins-by-ref.rs create mode 100644 src/test/ui/opeq.rs create mode 100644 src/test/ui/operator-associativity.rs create mode 100644 src/test/ui/operator-multidispatch.rs create mode 100644 src/test/ui/operator-overloading.rs create mode 100644 src/test/ui/optimization-fuel-0.rs create mode 100644 src/test/ui/optimization-fuel-0.stderr create mode 100644 src/test/ui/optimization-fuel-1.rs create mode 100644 src/test/ui/optimization-fuel-1.stderr create mode 100644 src/test/ui/option-ext.rs create mode 100644 src/test/ui/option-unwrap.rs create mode 100644 src/test/ui/out-of-stack.rs create mode 100644 src/test/ui/out-pointer-aliasing.rs create mode 100644 src/test/ui/output-slot-variants.rs create mode 100644 src/test/ui/over-constrained-vregs.rs create mode 100644 src/test/ui/overlap-doesnt-conflict-with-specialization.rs create mode 100644 src/test/ui/overlap-permitted-for-annotated-marker-traits.rs create mode 100644 src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef-count.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef-indexing.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef-order.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef-vtable.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef-xcrate.rs create mode 100644 src/test/ui/overloaded/overloaded-autoderef.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-object-one-arg.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-object-two-args.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-object-zero-args.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-param-vtables.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-simple.rs create mode 100644 src/test/ui/overloaded/overloaded-calls-zero-args.rs create mode 100644 src/test/ui/overloaded/overloaded-deref-count.rs create mode 100644 src/test/ui/overloaded/overloaded-deref.rs create mode 100644 src/test/ui/overloaded/overloaded-index-assoc-list.rs create mode 100644 src/test/ui/overloaded/overloaded-index-autoderef.rs create mode 100644 src/test/ui/overloaded/overloaded-index-in-field.rs create mode 100644 src/test/ui/overloaded/overloaded-index.rs create mode 100644 src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs create mode 100644 src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs create mode 100644 src/test/ui/owned-implies-static.rs create mode 100644 src/test/ui/packed/auxiliary/packed.rs create mode 100644 src/test/ui/packed/packed-struct-borrow-element.rs create mode 100644 src/test/ui/packed/packed-struct-drop-aligned.rs create mode 100644 src/test/ui/packed/packed-struct-generic-layout.rs create mode 100644 src/test/ui/packed/packed-struct-generic-size.rs create mode 100644 src/test/ui/packed/packed-struct-layout.rs create mode 100644 src/test/ui/packed/packed-struct-match.rs create mode 100644 src/test/ui/packed/packed-struct-optimized-enum.rs create mode 100644 src/test/ui/packed/packed-struct-size-xc.rs create mode 100644 src/test/ui/packed/packed-struct-size.rs create mode 100644 src/test/ui/packed/packed-struct-vec.rs create mode 100644 src/test/ui/packed/packed-tuple-struct-layout.rs create mode 100644 src/test/ui/packed/packed-tuple-struct-size.rs create mode 100644 src/test/ui/packed/packed-with-inference-vars-issue-61402.rs create mode 100644 src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs create mode 100644 src/test/ui/panic-runtime/abort.rs create mode 100644 src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs create mode 100644 src/test/ui/panic-runtime/link-to-abort.rs create mode 100644 src/test/ui/panic-runtime/link-to-unwind.rs create mode 100644 src/test/ui/panic-runtime/lto-abort.rs create mode 100644 src/test/ui/panic-runtime/lto-unwind.rs create mode 100644 src/test/ui/panic-uninitialized-zeroed.rs create mode 100644 src/test/ui/panics/panic-handler-chain.rs create mode 100644 src/test/ui/panics/panic-handler-flail-wildly.rs create mode 100644 src/test/ui/panics/panic-handler-set-twice.rs create mode 100644 src/test/ui/panics/panic-in-dtor-drops-fields.rs create mode 100644 src/test/ui/panics/panic-recover-propagate.rs create mode 100644 src/test/ui/panics/panic-safe.rs create mode 100644 src/test/ui/paren-free.rs create mode 100644 src/test/ui/parse-assoc-type-lt.rs create mode 100644 src/test/ui/parse-panic.rs create mode 100644 src/test/ui/parser-unicode-whitespace.rs create mode 100644 src/test/ui/path.rs create mode 100644 src/test/ui/paths-containing-nul.rs create mode 100644 src/test/ui/print-stdout-eprint-stderr.rs create mode 100644 src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs create mode 100644 src/test/ui/privacy/auxiliary/privacy_reexport.rs create mode 100644 src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs create mode 100644 src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs create mode 100644 src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs create mode 100644 src/test/ui/privacy/priv-impl-prim-ty.rs create mode 100644 src/test/ui/privacy/privacy-ns.rs create mode 100644 src/test/ui/privacy/privacy-reexport.rs create mode 100644 src/test/ui/privacy/private-class-field.rs create mode 100644 src/test/ui/privacy/pub-extern-privacy.rs create mode 100644 src/test/ui/privacy/pub-use-xcrate.rs create mode 100644 src/test/ui/privacy/pub_use_mods_xcrate_exe.rs create mode 100644 src/test/ui/proc-macro/add-impl.rs create mode 100644 src/test/ui/proc-macro/append-impl.rs create mode 100644 src/test/ui/proc-macro/attr-args.rs create mode 100644 src/test/ui/proc-macro/attr-cfg.rs create mode 100644 src/test/ui/proc-macro/attr-on-trait.rs create mode 100644 src/test/ui/proc-macro/auxiliary/add-impl.rs create mode 100644 src/test/ui/proc-macro/auxiliary/append-impl.rs create mode 100644 src/test/ui/proc-macro/auxiliary/attr-args.rs create mode 100644 src/test/ui/proc-macro/auxiliary/attr-cfg.rs create mode 100644 src/test/ui/proc-macro/auxiliary/attr-on-trait.rs create mode 100644 src/test/ui/proc-macro/auxiliary/bang-macro.rs create mode 100644 src/test/ui/proc-macro/auxiliary/call-site.rs create mode 100644 src/test/ui/proc-macro/auxiliary/count_compound_ops.rs create mode 100644 src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-a.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-atob.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-attr-cfg.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-ctod.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-nothing.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-same-struct.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs create mode 100644 src/test/ui/proc-macro/auxiliary/derive-union.rs create mode 100644 src/test/ui/proc-macro/auxiliary/double.rs create mode 100644 src/test/ui/proc-macro/auxiliary/empty-crate.rs create mode 100644 src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs create mode 100644 src/test/ui/proc-macro/auxiliary/external-crate-var.rs create mode 100644 src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs create mode 100644 src/test/ui/proc-macro/auxiliary/hygiene_example.rs create mode 100644 src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs create mode 100644 src/test/ui/proc-macro/auxiliary/issue-39889.rs create mode 100644 src/test/ui/proc-macro/auxiliary/issue-42708.rs create mode 100644 src/test/ui/proc-macro/auxiliary/issue-50061.rs create mode 100644 src/test/ui/proc-macro/auxiliary/modify-ast.rs create mode 100644 src/test/ui/proc-macro/auxiliary/negative-token.rs create mode 100644 src/test/ui/proc-macro/auxiliary/not-joint.rs create mode 100644 src/test/ui/proc-macro/auxiliary/span-api-tests.rs create mode 100644 src/test/ui/proc-macro/auxiliary/span-test-macros.rs create mode 100644 src/test/ui/proc-macro/bang-macro.rs create mode 100644 src/test/ui/proc-macro/call-site.rs create mode 100644 src/test/ui/proc-macro/count_compound_ops.rs create mode 100644 src/test/ui/proc-macro/crate-var.rs create mode 100644 src/test/ui/proc-macro/custom-attr-only-one-derive.rs create mode 100644 src/test/ui/proc-macro/derive-attr-cfg.rs create mode 100644 src/test/ui/proc-macro/derive-b.rs create mode 100644 src/test/ui/proc-macro/derive-same-struct.rs create mode 100644 src/test/ui/proc-macro/derive-same-struct.stdout create mode 100644 src/test/ui/proc-macro/derive-test.rs create mode 100644 src/test/ui/proc-macro/derive-two-attrs.rs create mode 100644 src/test/ui/proc-macro/derive-union.rs create mode 100644 src/test/ui/proc-macro/empty-crate.rs create mode 100644 src/test/ui/proc-macro/expand-with-a-macro.rs create mode 100644 src/test/ui/proc-macro/gen-lifetime-token.rs create mode 100644 src/test/ui/proc-macro/hygiene_example.rs create mode 100644 src/test/ui/proc-macro/issue-39889.rs create mode 100644 src/test/ui/proc-macro/issue-42708.rs create mode 100644 src/test/ui/proc-macro/issue-50061.rs create mode 100644 src/test/ui/proc-macro/load-two.rs create mode 100644 src/test/ui/proc-macro/modify-ast.rs create mode 100644 src/test/ui/proc-macro/negative-token.rs create mode 100644 src/test/ui/proc-macro/not-joint.rs create mode 100644 src/test/ui/proc-macro/smoke.rs create mode 100644 src/test/ui/proc-macro/span-api-tests.rs create mode 100644 src/test/ui/proc-macro/struct-field-macro.rs create mode 100644 src/test/ui/proc_macro.rs create mode 100644 src/test/ui/process/process-envs.rs create mode 100644 src/test/ui/process/process-exit.rs create mode 100644 src/test/ui/process/process-remove-from-env.rs create mode 100644 src/test/ui/process/process-sigpipe.rs create mode 100644 src/test/ui/process/process-spawn-nonexistent.rs create mode 100644 src/test/ui/process/process-spawn-with-unicode-params.rs create mode 100644 src/test/ui/process/process-status-inherits-stdin.rs create mode 100644 src/test/ui/project-cache-issue-31849.rs create mode 100644 src/test/ui/project-cache-issue-37154.rs create mode 100644 src/test/ui/project-defer-unification.rs create mode 100644 src/test/ui/pure-sum.rs create mode 100644 src/test/ui/purity-infer.rs create mode 100644 src/test/ui/range-type-infer.rs create mode 100644 src/test/ui/range.rs create mode 100644 src/test/ui/range_inclusive.rs create mode 100644 src/test/ui/range_inclusive_gate.rs create mode 100644 src/test/ui/ranges-precedence.rs create mode 100644 src/test/ui/raw-fat-ptr.rs create mode 100644 src/test/ui/raw-str.rs create mode 100644 src/test/ui/rcvr-borrowed-to-region.rs create mode 100644 src/test/ui/reachable-unnameable-items.rs create mode 100644 src/test/ui/reachable-unnameable-type-alias.rs create mode 100644 src/test/ui/readalias.rs create mode 100644 src/test/ui/realloc-16687.rs create mode 100644 src/test/ui/reexport-should-still-link.rs create mode 100644 src/test/ui/reexport-star.rs create mode 100644 src/test/ui/reexport-test-harness-main.rs create mode 100644 src/test/ui/refer-to-other-statics-by-value.rs create mode 100644 src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs create mode 100644 src/test/ui/regions/regions-addr-of-ret.rs create mode 100644 src/test/ui/regions/regions-assoc-type-region-bound.rs create mode 100644 src/test/ui/regions/regions-assoc-type-static-bound.rs create mode 100644 src/test/ui/regions/regions-borrow-at.rs create mode 100644 src/test/ui/regions/regions-borrow-evec-fixed.rs create mode 100644 src/test/ui/regions/regions-borrow-evec-uniq.rs create mode 100644 src/test/ui/regions/regions-borrow-uniq.rs create mode 100644 src/test/ui/regions/regions-bot.rs create mode 100644 src/test/ui/regions/regions-bound-lists-feature-gate-2.rs create mode 100644 src/test/ui/regions/regions-bound-lists-feature-gate.rs create mode 100644 src/test/ui/regions/regions-close-over-type-parameter-successfully.rs create mode 100644 src/test/ui/regions/regions-copy-closure.rs create mode 100644 src/test/ui/regions/regions-creating-enums2.rs create mode 100644 src/test/ui/regions/regions-creating-enums5.rs create mode 100644 src/test/ui/regions/regions-debruijn-of-object.rs create mode 100644 src/test/ui/regions/regions-dependent-addr-of.rs create mode 100644 src/test/ui/regions/regions-dependent-autofn.rs create mode 100644 src/test/ui/regions/regions-dependent-autoslice.rs create mode 100644 src/test/ui/regions/regions-dependent-let-ref.rs create mode 100644 src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs create mode 100644 src/test/ui/regions/regions-early-bound-trait-param.rs create mode 100644 src/test/ui/regions/regions-early-bound-used-in-bound-method.rs create mode 100644 src/test/ui/regions/regions-early-bound-used-in-bound.rs create mode 100644 src/test/ui/regions/regions-early-bound-used-in-type-param.rs create mode 100644 src/test/ui/regions/regions-escape-into-other-fn.rs create mode 100644 src/test/ui/regions/regions-expl-self.rs create mode 100644 src/test/ui/regions/regions-fn-subtyping-2.rs create mode 100644 src/test/ui/regions/regions-fn-subtyping.rs create mode 100644 src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs create mode 100644 src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs create mode 100644 src/test/ui/regions/regions-infer-borrow-scope-view.rs create mode 100644 src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs create mode 100644 src/test/ui/regions/regions-infer-borrow-scope.rs create mode 100644 src/test/ui/regions/regions-infer-call-2.rs create mode 100644 src/test/ui/regions/regions-infer-call.rs create mode 100644 src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs create mode 100644 src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs create mode 100644 src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs create mode 100644 src/test/ui/regions/regions-infer-static-from-proc.rs create mode 100644 src/test/ui/regions/regions-issue-21422.rs create mode 100644 src/test/ui/regions/regions-issue-22246.rs create mode 100644 src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs create mode 100644 src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs create mode 100644 src/test/ui/regions/regions-link-fn-args.rs create mode 100644 src/test/ui/regions/regions-lub-ref-ref-rc.rs create mode 100644 src/test/ui/regions/regions-mock-codegen.rs create mode 100644 src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs create mode 100644 src/test/ui/regions/regions-no-variance-from-fn-generics.rs create mode 100644 src/test/ui/regions/regions-nullary-variant.rs create mode 100644 src/test/ui/regions/regions-params.rs create mode 100644 src/test/ui/regions/regions-reassign-let-bound-pointer.rs create mode 100644 src/test/ui/regions/regions-reassign-match-bound-pointer.rs create mode 100644 src/test/ui/regions/regions-refcell.rs create mode 100644 src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs create mode 100644 src/test/ui/regions/regions-return-interior-of-option.rs create mode 100644 src/test/ui/regions/regions-scope-chain-example.rs create mode 100644 src/test/ui/regions/regions-self-impls.rs create mode 100644 src/test/ui/regions/regions-self-in-enums.rs create mode 100644 src/test/ui/regions/regions-simple.rs create mode 100644 src/test/ui/regions/regions-static-closure.rs create mode 100644 src/test/ui/regions/regions-trait-object-1.rs create mode 100644 src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs create mode 100644 src/test/ui/regions/regions-variance-covariant-use-covariant.rs create mode 100644 src/test/ui/repeat-expr-in-static.rs create mode 100644 src/test/ui/repr_c_int_align.rs create mode 100644 src/test/ui/resolve-issue-2428.rs create mode 100644 src/test/ui/resolve-pseudo-shadowing.rs create mode 100644 src/test/ui/resource-assign-is-not-copy.rs create mode 100644 src/test/ui/resource-destruct.rs create mode 100644 src/test/ui/result-opt-conversions.rs create mode 100644 src/test/ui/ret-bang.rs create mode 100644 src/test/ui/ret-none.rs create mode 100644 src/test/ui/return-nil.rs create mode 100644 src/test/ui/rfcs/rfc-1014-2.rs create mode 100644 src/test/ui/rfcs/rfc-1014.rs create mode 100644 src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs create mode 100644 src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs create mode 100644 src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs create mode 100644 src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs create mode 100644 src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs create mode 100644 src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs create mode 100644 src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs create mode 100644 src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs create mode 100644 src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs create mode 100644 src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs create mode 100644 src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs create mode 100644 src/test/ui/rfcs/rfc1445/eq-allows-match.rs create mode 100644 src/test/ui/rfcs/rfc1623.rs create mode 100644 src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs create mode 100644 src/test/ui/rfcs/rfc1717/library-override.rs create mode 100644 src/test/ui/rfcs/rfc1857-drop-order.rs create mode 100644 src/test/ui/running-with-no-runtime.rs create mode 100644 src/test/ui/rustc-rust-log.rs create mode 100644 src/test/ui/rvalue-static-promotion.rs create mode 100644 src/test/ui/segfault-no-out-of-stack.rs create mode 100644 src/test/ui/semistatement-in-lambda.rs create mode 100644 src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs create mode 100644 src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs create mode 100644 src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs create mode 100644 src/test/ui/sepcomp/sepcomp-cci.rs create mode 100644 src/test/ui/sepcomp/sepcomp-extern.rs create mode 100644 src/test/ui/sepcomp/sepcomp-fns-backwards.rs create mode 100644 src/test/ui/sepcomp/sepcomp-fns.rs create mode 100644 src/test/ui/sepcomp/sepcomp-lib-lto.rs create mode 100644 src/test/ui/sepcomp/sepcomp-lib.rs create mode 100644 src/test/ui/sepcomp/sepcomp-statics.rs create mode 100644 src/test/ui/sepcomp/sepcomp-unwind.rs create mode 100644 src/test/ui/seq-compare.rs create mode 100644 src/test/ui/shadow.rs create mode 100644 src/test/ui/shadowed-use-visibility.rs create mode 100644 src/test/ui/shebang.rs create mode 100644 src/test/ui/signal-alternate-stack-cleanup.rs create mode 100644 src/test/ui/signal-exit-status.rs create mode 100644 src/test/ui/sigpipe-should-be-ignored.rs create mode 100644 src/test/ui/simd/simd-generics.rs create mode 100644 src/test/ui/simd/simd-intrinsic-float-math.rs create mode 100644 src/test/ui/simd/simd-intrinsic-float-minmax.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-bitmask.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-cast.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-comparison.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-elements.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-gather.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-reduction.rs create mode 100644 src/test/ui/simd/simd-intrinsic-generic-select.rs create mode 100644 src/test/ui/simd/simd-size-align.rs create mode 100644 src/test/ui/simd/simd-target-feature-mixup.rs create mode 100644 src/test/ui/simd/simd-type.rs create mode 100644 src/test/ui/simple-infer.rs create mode 100644 src/test/ui/simple_global_asm.rs create mode 100644 src/test/ui/size-and-align.rs create mode 100644 src/test/ui/sized-borrowed-pointer.rs create mode 100644 src/test/ui/sized-owned-pointer.rs create mode 100644 src/test/ui/sleep.rs create mode 100644 src/test/ui/slowparse-bstring.rs create mode 100644 src/test/ui/slowparse-string.rs create mode 100644 src/test/ui/specialization/assoc-ty-graph-cycle.rs create mode 100644 src/test/ui/specialization/auxiliary/cross_crates_defaults.rs create mode 100644 src/test/ui/specialization/auxiliary/go_trait.rs create mode 100644 src/test/ui/specialization/auxiliary/specialization_cross_crate.rs create mode 100644 src/test/ui/specialization/cross-crate-defaults.rs create mode 100644 src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs create mode 100644 src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs create mode 100644 src/test/ui/specialization/defaultimpl/out-of-order.rs create mode 100644 src/test/ui/specialization/defaultimpl/overlap-projection.rs create mode 100644 src/test/ui/specialization/defaultimpl/projection.rs create mode 100644 src/test/ui/specialization/issue-50452.rs create mode 100644 src/test/ui/specialization/specialization-allowed-cross-crate.rs create mode 100644 src/test/ui/specialization/specialization-assoc-fns.rs create mode 100644 src/test/ui/specialization/specialization-basics.rs create mode 100644 src/test/ui/specialization/specialization-cross-crate-no-gate.rs create mode 100644 src/test/ui/specialization/specialization-cross-crate.rs create mode 100644 src/test/ui/specialization/specialization-default-methods.rs create mode 100644 src/test/ui/specialization/specialization-on-projection.rs create mode 100644 src/test/ui/specialization/specialization-out-of-order.rs create mode 100644 src/test/ui/specialization/specialization-overlap-projection.rs create mode 100644 src/test/ui/specialization/specialization-projection-alias.rs create mode 100644 src/test/ui/specialization/specialization-projection.rs create mode 100644 src/test/ui/specialization/specialization-super-traits.rs create mode 100644 src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs create mode 100644 src/test/ui/specialization/specialization-translate-projections-with-params.rs create mode 100644 src/test/ui/specialization/specialization-translate-projections.rs create mode 100644 src/test/ui/sse2.rs create mode 100644 src/test/ui/stable-addr-of.rs create mode 100644 src/test/ui/stack-probes-lto.rs create mode 100644 src/test/ui/stack-probes.rs create mode 100644 src/test/ui/statics/auxiliary/static-function-pointer-aux.rs create mode 100644 src/test/ui/statics/auxiliary/static-methods-crate.rs create mode 100644 src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs create mode 100644 src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs create mode 100644 src/test/ui/statics/auxiliary/static_mut_xc.rs create mode 100644 src/test/ui/statics/static-fn-inline-xc.rs create mode 100644 src/test/ui/statics/static-fn-trait-xc.rs create mode 100644 src/test/ui/statics/static-function-pointer-xc.rs create mode 100644 src/test/ui/statics/static-function-pointer.rs create mode 100644 src/test/ui/statics/static-impl.rs create mode 100644 src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs create mode 100644 src/test/ui/statics/static-method-xcrate.rs create mode 100644 src/test/ui/statics/static-methods-in-traits.rs create mode 100644 src/test/ui/statics/static-methods-in-traits2.rs create mode 100644 src/test/ui/statics/static-mut-foreign.rs create mode 100644 src/test/ui/statics/static-mut-xc.rs create mode 100644 src/test/ui/statics/static-recursive.rs create mode 100644 src/test/ui/stdio-is-blocking.rs create mode 100644 src/test/ui/str-concat.rs create mode 100644 src/test/ui/str-multiline.rs create mode 100644 src/test/ui/string-box-error.rs create mode 100644 src/test/ui/string-escapes.rs create mode 100644 src/test/ui/struct-ctor-mangling.rs create mode 100644 src/test/ui/structs-enums/align-enum.rs create mode 100644 src/test/ui/structs-enums/align-struct.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_2.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_3.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_4.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_6.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_cast.rs create mode 100644 src/test/ui/structs-enums/auxiliary/cci_class_trait.rs create mode 100644 src/test/ui/structs-enums/auxiliary/empty-struct.rs create mode 100644 src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs create mode 100644 src/test/ui/structs-enums/auxiliary/namespaced_enums.rs create mode 100644 src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs create mode 100644 src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs create mode 100644 src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs create mode 100644 src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs create mode 100644 src/test/ui/structs-enums/borrow-tuple-fields.rs create mode 100644 src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs create mode 100644 src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs create mode 100644 src/test/ui/structs-enums/class-cast-to-trait.rs create mode 100644 src/test/ui/structs-enums/class-dtor.rs create mode 100644 src/test/ui/structs-enums/class-exports.rs create mode 100644 src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs create mode 100644 src/test/ui/structs-enums/class-implement-trait-cross-crate.rs create mode 100644 src/test/ui/structs-enums/class-implement-traits.rs create mode 100644 src/test/ui/structs-enums/class-method-cross-crate.rs create mode 100644 src/test/ui/structs-enums/class-methods-cross-crate.rs create mode 100644 src/test/ui/structs-enums/class-methods.rs create mode 100644 src/test/ui/structs-enums/class-poly-methods-cross-crate.rs create mode 100644 src/test/ui/structs-enums/class-poly-methods.rs create mode 100644 src/test/ui/structs-enums/class-separate-impl.rs create mode 100644 src/test/ui/structs-enums/class-str-field.rs create mode 100644 src/test/ui/structs-enums/class-typarams.rs create mode 100644 src/test/ui/structs-enums/classes-cross-crate.rs create mode 100644 src/test/ui/structs-enums/classes-self-referential.rs create mode 100644 src/test/ui/structs-enums/classes-simple-cross-crate.rs create mode 100644 src/test/ui/structs-enums/classes-simple-method.rs create mode 100644 src/test/ui/structs-enums/classes-simple.rs create mode 100644 src/test/ui/structs-enums/classes.rs create mode 100644 src/test/ui/structs-enums/codegen-tag-static-padding.rs create mode 100644 src/test/ui/structs-enums/compare-generic-enums.rs create mode 100644 src/test/ui/structs-enums/discrim-explicit-23030.rs create mode 100644 src/test/ui/structs-enums/empty-struct-braces.rs create mode 100644 src/test/ui/structs-enums/empty-tag.rs create mode 100644 src/test/ui/structs-enums/enum-alignment.rs create mode 100644 src/test/ui/structs-enums/enum-clike-ffi-as-int.rs create mode 100644 src/test/ui/structs-enums/enum-discr.rs create mode 100644 src/test/ui/structs-enums/enum-discrim-autosizing.rs create mode 100644 src/test/ui/structs-enums/enum-discrim-manual-sizing.rs create mode 100644 src/test/ui/structs-enums/enum-discrim-range-overflow.rs create mode 100644 src/test/ui/structs-enums/enum-discrim-width-stuff.rs create mode 100644 src/test/ui/structs-enums/enum-disr-val-pretty.rs create mode 100644 src/test/ui/structs-enums/enum-export-inheritance.rs create mode 100644 src/test/ui/structs-enums/enum-layout-optimization.rs create mode 100644 src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs create mode 100644 src/test/ui/structs-enums/enum-non-c-like-repr-c.rs create mode 100644 src/test/ui/structs-enums/enum-non-c-like-repr-int.rs create mode 100644 src/test/ui/structs-enums/enum-null-pointer-opt.rs create mode 100644 src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs create mode 100644 src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs create mode 100644 src/test/ui/structs-enums/enum-univariant-repr.rs create mode 100644 src/test/ui/structs-enums/enum-variants.rs create mode 100644 src/test/ui/structs-enums/enum-vec-initializer.rs create mode 100644 src/test/ui/structs-enums/export-abstract-tag.rs create mode 100644 src/test/ui/structs-enums/export-tag-variant.rs create mode 100644 src/test/ui/structs-enums/expr-if-struct.rs create mode 100644 src/test/ui/structs-enums/expr-match-struct.rs create mode 100644 src/test/ui/structs-enums/field-destruction-order.rs create mode 100644 src/test/ui/structs-enums/foreign-struct.rs create mode 100644 src/test/ui/structs-enums/functional-struct-upd.rs create mode 100644 src/test/ui/structs-enums/ivec-tag.rs create mode 100644 src/test/ui/structs-enums/module-qualified-struct-destructure.rs create mode 100644 src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs create mode 100644 src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs create mode 100644 src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs create mode 100644 src/test/ui/structs-enums/namespaced-enum-glob-import.rs create mode 100644 src/test/ui/structs-enums/namespaced-enums-xcrate.rs create mode 100644 src/test/ui/structs-enums/namespaced-enums.rs create mode 100644 src/test/ui/structs-enums/nested-enum-same-names.rs create mode 100644 src/test/ui/structs-enums/newtype-struct-drop-run.rs create mode 100644 src/test/ui/structs-enums/newtype-struct-with-dtor.rs create mode 100644 src/test/ui/structs-enums/newtype-struct-xc-2.rs create mode 100644 src/test/ui/structs-enums/newtype-struct-xc.rs create mode 100644 src/test/ui/structs-enums/nonzero-enum.rs create mode 100644 src/test/ui/structs-enums/numeric-fields.rs create mode 100644 src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs create mode 100644 src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs create mode 100644 src/test/ui/structs-enums/rec-align-u32.rs create mode 100644 src/test/ui/structs-enums/rec-align-u64.rs create mode 100644 src/test/ui/structs-enums/rec-auto.rs create mode 100644 src/test/ui/structs-enums/rec-extend.rs create mode 100644 src/test/ui/structs-enums/rec-tup.rs create mode 100644 src/test/ui/structs-enums/rec.rs create mode 100644 src/test/ui/structs-enums/record-pat.rs create mode 100644 src/test/ui/structs-enums/resource-in-struct.rs create mode 100644 src/test/ui/structs-enums/simple-generic-tag.rs create mode 100644 src/test/ui/structs-enums/simple-match-generic-tag.rs create mode 100644 src/test/ui/structs-enums/small-enum-range-edge.rs create mode 100644 src/test/ui/structs-enums/small-enums-with-fields.rs create mode 100644 src/test/ui/structs-enums/struct-aliases-xcrate.rs create mode 100644 src/test/ui/structs-enums/struct-aliases.rs create mode 100644 src/test/ui/structs-enums/struct-destructuring-cross-crate.rs create mode 100644 src/test/ui/structs-enums/struct-field-shorthand.rs create mode 100644 src/test/ui/structs-enums/struct-like-variant-construct.rs create mode 100644 src/test/ui/structs-enums/struct-like-variant-match.rs create mode 100644 src/test/ui/structs-enums/struct-lit-functional-no-fields.rs create mode 100644 src/test/ui/structs-enums/struct-literal-dtor.rs create mode 100644 src/test/ui/structs-enums/struct-new-as-field-name.rs create mode 100644 src/test/ui/structs-enums/struct-order-of-eval-1.rs create mode 100644 src/test/ui/structs-enums/struct-order-of-eval-2.rs create mode 100644 src/test/ui/structs-enums/struct-order-of-eval-3.rs create mode 100644 src/test/ui/structs-enums/struct-order-of-eval-4.rs create mode 100644 src/test/ui/structs-enums/struct-partial-move-1.rs create mode 100644 src/test/ui/structs-enums/struct-partial-move-2.rs create mode 100644 src/test/ui/structs-enums/struct-path-associated-type.rs create mode 100644 src/test/ui/structs-enums/struct-path-self.rs create mode 100644 src/test/ui/structs-enums/struct-pattern-matching.rs create mode 100644 src/test/ui/structs-enums/struct-return.rs create mode 100644 src/test/ui/structs-enums/struct-variant-field-visibility.rs create mode 100644 src/test/ui/structs-enums/struct_variant_xc.rs create mode 100644 src/test/ui/structs-enums/struct_variant_xc_match.rs create mode 100644 src/test/ui/structs-enums/tag-align-dyn-u64.rs create mode 100644 src/test/ui/structs-enums/tag-align-dyn-variants.rs create mode 100644 src/test/ui/structs-enums/tag-align-shape.rs create mode 100644 src/test/ui/structs-enums/tag-align-u64.rs create mode 100644 src/test/ui/structs-enums/tag-disr-val-shape.rs create mode 100644 src/test/ui/structs-enums/tag-exports.rs create mode 100644 src/test/ui/structs-enums/tag-in-block.rs create mode 100644 src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs create mode 100644 src/test/ui/structs-enums/tag-variant-disr-val.rs create mode 100644 src/test/ui/structs-enums/tag.rs create mode 100644 src/test/ui/structs-enums/tuple-struct-construct.rs create mode 100644 src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs create mode 100644 src/test/ui/structs-enums/tuple-struct-destructuring.rs create mode 100644 src/test/ui/structs-enums/tuple-struct-matching.rs create mode 100644 src/test/ui/structs-enums/tuple-struct-trivial.rs create mode 100644 src/test/ui/structs-enums/uninstantiable-struct.rs create mode 100644 src/test/ui/structs-enums/unit-like-struct-drop-run.rs create mode 100644 src/test/ui/structs-enums/unit-like-struct.rs create mode 100644 src/test/ui/structs-enums/variant-structs-trivial.rs create mode 100644 src/test/ui/structured-compare.rs create mode 100644 src/test/ui/super-fast-paren-parsing.rs create mode 100644 src/test/ui/super.rs create mode 100644 src/test/ui/supported-cast.rs create mode 100644 src/test/ui/svh-add-nothing.rs create mode 100644 src/test/ui/swap-1.rs create mode 100644 src/test/ui/swap-2.rs create mode 100644 src/test/ui/swap-overlapping.rs create mode 100644 src/test/ui/tail-call-arg-leak.rs create mode 100644 src/test/ui/tail-cps.rs create mode 100644 src/test/ui/tail-direct.rs create mode 100644 src/test/ui/tcp-stress.rs create mode 100644 src/test/ui/terminate-in-initializer.rs create mode 100644 src/test/ui/test-allow-dead-extern-static-no-warning.rs create mode 100644 src/test/ui/test-allow-fail-attr.rs create mode 100644 src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs create mode 100644 src/test/ui/test-main-not-dead-attr.rs create mode 100644 src/test/ui/test-main-not-dead.rs create mode 100644 src/test/ui/test-runner-hides-buried-main.rs create mode 100644 src/test/ui/test-runner-hides-main.rs create mode 100644 src/test/ui/test-runner-hides-start.rs create mode 100644 src/test/ui/test-should-fail-good-message.rs create mode 100644 src/test/ui/test-vs-cfg-test.rs create mode 100644 src/test/ui/thin-lto-global-allocator.rs create mode 100644 src/test/ui/thinlto/all-crates.rs create mode 100644 src/test/ui/thinlto/auxiliary/dylib.rs create mode 100644 src/test/ui/thinlto/auxiliary/msvc-imp-present.rs create mode 100644 src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs create mode 100644 src/test/ui/thinlto/dylib-works.rs create mode 100644 src/test/ui/thinlto/msvc-imp-present.rs create mode 100644 src/test/ui/thinlto/thin-lto-inlines.rs create mode 100644 src/test/ui/thinlto/thin-lto-inlines2.rs create mode 100644 src/test/ui/thinlto/weak-works.rs create mode 100644 src/test/ui/thread-local-not-in-prelude.rs create mode 100644 src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs create mode 100644 src/test/ui/threads-sendsync/comm.rs create mode 100644 src/test/ui/threads-sendsync/send-is-not-static-par-for.rs create mode 100644 src/test/ui/threads-sendsync/send-resource.rs create mode 100644 src/test/ui/threads-sendsync/send-type-inference.rs create mode 100644 src/test/ui/threads-sendsync/send_str_hashmap.rs create mode 100644 src/test/ui/threads-sendsync/send_str_treemap.rs create mode 100644 src/test/ui/threads-sendsync/sendable-class.rs create mode 100644 src/test/ui/threads-sendsync/sendfn-is-a-block.rs create mode 100644 src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs create mode 100644 src/test/ui/threads-sendsync/spawn-fn.rs create mode 100644 src/test/ui/threads-sendsync/spawn-types.rs create mode 100644 src/test/ui/threads-sendsync/spawn.rs create mode 100644 src/test/ui/threads-sendsync/spawn2.rs create mode 100644 src/test/ui/threads-sendsync/spawning-with-debug.rs create mode 100644 src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs create mode 100644 src/test/ui/threads-sendsync/sync-send-atomics.rs create mode 100644 src/test/ui/threads-sendsync/sync-send-in-std.rs create mode 100644 src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs create mode 100644 src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-0.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-1.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-10.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-11.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-12.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-13.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-14.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-15.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-16.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-17.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-3.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-4.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-5.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-6.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-7.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-9.rs create mode 100644 src/test/ui/threads-sendsync/task-comm-chan-nil.rs create mode 100644 src/test/ui/threads-sendsync/task-life-0.rs create mode 100644 src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs create mode 100644 src/test/ui/threads-sendsync/task-stderr.rs create mode 100644 src/test/ui/threads-sendsync/thread-local-extern-static.rs create mode 100644 src/test/ui/threads-sendsync/thread-local-syntax.rs create mode 100644 src/test/ui/threads-sendsync/threads.rs create mode 100644 src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs create mode 100644 src/test/ui/threads-sendsync/tls-init-on-init.rs create mode 100644 src/test/ui/threads-sendsync/tls-try-with.rs create mode 100644 src/test/ui/tool_attributes.rs create mode 100644 src/test/ui/tool_lints_2018_preview.rs create mode 100644 src/test/ui/trailing-comma.rs create mode 100644 src/test/ui/traits/anon-trait-static-method.rs create mode 100644 src/test/ui/traits/anon_trait_static_method_exe.rs create mode 100644 src/test/ui/traits/assignability-trait.rs create mode 100644 src/test/ui/traits/astconv-cycle-between-trait-and-type.rs create mode 100644 src/test/ui/traits/augmented-assignments-trait.rs create mode 100644 src/test/ui/traits/auto-traits.rs create mode 100644 src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs create mode 100644 src/test/ui/traits/auxiliary/go_trait.rs create mode 100644 src/test/ui/traits/auxiliary/trait_alias.rs create mode 100644 src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs create mode 100644 src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs create mode 100644 src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs create mode 100644 src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs create mode 100644 src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs create mode 100644 src/test/ui/traits/auxiliary/trait_xc_call_aux.rs create mode 100644 src/test/ui/traits/auxiliary/traitimpl.rs create mode 100644 src/test/ui/traits/cycle-trait-type-trait.rs create mode 100644 src/test/ui/traits/default-method-supertrait-vtable.rs create mode 100644 src/test/ui/traits/dyn-trait.rs create mode 100644 src/test/ui/traits/fmt-pointer-trait.rs create mode 100644 src/test/ui/traits/impl-implicit-trait.rs create mode 100644 src/test/ui/traits/impl-inherent-prefer-over-trait.rs create mode 100644 src/test/ui/traits/infer-from-object-trait-issue-26952.rs create mode 100644 src/test/ui/traits/inherent-trait-method-order.rs create mode 100644 src/test/ui/traits/kindck-owned-trait-contains-1.rs create mode 100644 src/test/ui/traits/multiple-trait-bounds.rs create mode 100644 src/test/ui/traits/object-one-type-two-traits.rs create mode 100644 src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs create mode 100644 src/test/ui/traits/overlap-permitted-for-marker-traits.rs create mode 100644 src/test/ui/traits/parameterized-trait-with-bounds.rs create mode 100644 src/test/ui/traits/principal-less-trait-objects.rs create mode 100644 src/test/ui/traits/supertrait-default-generics.rs create mode 100644 src/test/ui/traits/syntax-trait-polarity.rs create mode 100644 src/test/ui/traits/trait-alias-import-cross-crate.rs create mode 100644 src/test/ui/traits/trait-alias-import.rs create mode 100644 src/test/ui/traits/trait-bounds-basic.rs create mode 100644 src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs create mode 100644 src/test/ui/traits/trait-bounds-in-arc.rs create mode 100644 src/test/ui/traits/trait-bounds-recursion.rs create mode 100644 src/test/ui/traits/trait-bounds.rs create mode 100644 src/test/ui/traits/trait-cache-issue-18209.rs create mode 100644 src/test/ui/traits/trait-coercion-generic.rs create mode 100644 src/test/ui/traits/trait-coercion.rs create mode 100644 src/test/ui/traits/trait-composition-trivial.rs create mode 100644 src/test/ui/traits/trait-copy-guessing.rs create mode 100644 src/test/ui/traits/trait-default-method-bound-subst.rs create mode 100644 src/test/ui/traits/trait-default-method-bound-subst2.rs create mode 100644 src/test/ui/traits/trait-default-method-bound-subst3.rs create mode 100644 src/test/ui/traits/trait-default-method-bound-subst4.rs create mode 100644 src/test/ui/traits/trait-default-method-bound.rs create mode 100644 src/test/ui/traits/trait-default-method-xc-2.rs create mode 100644 src/test/ui/traits/trait-default-method-xc.rs create mode 100644 src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs create mode 100644 src/test/ui/traits/trait-generic.rs create mode 100644 src/test/ui/traits/trait-impl-2.rs create mode 100644 src/test/ui/traits/trait-impl.rs create mode 100644 src/test/ui/traits/trait-inheritance-auto-xc-2.rs create mode 100644 src/test/ui/traits/trait-inheritance-auto-xc.rs create mode 100644 src/test/ui/traits/trait-inheritance-auto.rs create mode 100644 src/test/ui/traits/trait-inheritance-call-bound-inherited.rs create mode 100644 src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs create mode 100644 src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs create mode 100644 src/test/ui/traits/trait-inheritance-cast.rs create mode 100644 src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs create mode 100644 src/test/ui/traits/trait-inheritance-cross-trait-call.rs create mode 100644 src/test/ui/traits/trait-inheritance-diamond.rs create mode 100644 src/test/ui/traits/trait-inheritance-multiple-inheritors.rs create mode 100644 src/test/ui/traits/trait-inheritance-multiple-params.rs create mode 100644 src/test/ui/traits/trait-inheritance-num.rs create mode 100644 src/test/ui/traits/trait-inheritance-num0.rs create mode 100644 src/test/ui/traits/trait-inheritance-num1.rs create mode 100644 src/test/ui/traits/trait-inheritance-num2.rs create mode 100644 src/test/ui/traits/trait-inheritance-num3.rs create mode 100644 src/test/ui/traits/trait-inheritance-num5.rs create mode 100644 src/test/ui/traits/trait-inheritance-overloading-simple.rs create mode 100644 src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs create mode 100644 src/test/ui/traits/trait-inheritance-overloading.rs create mode 100644 src/test/ui/traits/trait-inheritance-self-in-supertype.rs create mode 100644 src/test/ui/traits/trait-inheritance-self.rs create mode 100644 src/test/ui/traits/trait-inheritance-simple.rs create mode 100644 src/test/ui/traits/trait-inheritance-static.rs create mode 100644 src/test/ui/traits/trait-inheritance-static2.rs create mode 100644 src/test/ui/traits/trait-inheritance-subst.rs create mode 100644 src/test/ui/traits/trait-inheritance-subst2.rs create mode 100644 src/test/ui/traits/trait-inheritance-visibility.rs create mode 100644 src/test/ui/traits/trait-inheritance2.rs create mode 100644 src/test/ui/traits/trait-item-inside-macro.rs create mode 100644 src/test/ui/traits/trait-object-auto-dedup.rs create mode 100644 src/test/ui/traits/trait-object-exclusion.rs create mode 100644 src/test/ui/traits/trait-object-generics.rs create mode 100644 src/test/ui/traits/trait-object-lifetime-first.rs create mode 100644 src/test/ui/traits/trait-object-with-lifetime-bound.rs create mode 100644 src/test/ui/traits/trait-region-pointer-simple.rs create mode 100644 src/test/ui/traits/trait-safety-ok-cc.rs create mode 100644 src/test/ui/traits/trait-safety-ok.rs create mode 100644 src/test/ui/traits/trait-static-method-overwriting.rs create mode 100644 src/test/ui/traits/trait-to-str.rs create mode 100644 src/test/ui/traits/trait-where-clause-vs-impl.rs create mode 100644 src/test/ui/traits/trait-with-bounds-default.rs create mode 100644 src/test/ui/traits/traits-assoc-type-in-supertrait.rs create mode 100644 src/test/ui/traits/traits-conditional-dispatch.rs create mode 100644 src/test/ui/traits/traits-conditional-model-fn.rs create mode 100644 src/test/ui/traits/traits-default-method-macro.rs create mode 100644 src/test/ui/traits/traits-default-method-mut.rs create mode 100644 src/test/ui/traits/traits-default-method-self.rs create mode 100644 src/test/ui/traits/traits-default-method-trivial.rs create mode 100644 src/test/ui/traits/traits-elaborate-type-region.rs create mode 100644 src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs create mode 100644 src/test/ui/traits/traits-issue-22019.rs create mode 100644 src/test/ui/traits/traits-issue-22110.rs create mode 100644 src/test/ui/traits/traits-issue-22655.rs create mode 100644 src/test/ui/traits/traits-issue-23003.rs create mode 100644 src/test/ui/traits/traits-issue-26339.rs create mode 100644 src/test/ui/traits/traits-multidispatch-infer-convert-target.rs create mode 100644 src/test/ui/traits/traits-repeated-supertrait.rs create mode 100644 src/test/ui/traits/ufcs-trait-object.rs create mode 100644 src/test/ui/traits/use-trait-before-def.rs create mode 100644 src/test/ui/transmute-non-immediate-to-immediate.rs create mode 100644 src/test/ui/transmute-specialization.rs create mode 100644 src/test/ui/trivial-message.rs create mode 100644 src/test/ui/try-block.rs create mode 100644 src/test/ui/try-from-int-error-partial-eq.rs create mode 100644 src/test/ui/try-is-identifier-edition2015.rs create mode 100644 src/test/ui/try-operator-custom.rs create mode 100644 src/test/ui/try-operator-hygiene.rs create mode 100644 src/test/ui/try-operator.rs create mode 100644 src/test/ui/try-wait.rs create mode 100644 src/test/ui/try_from.rs create mode 100644 src/test/ui/tup.rs create mode 100644 src/test/ui/tuple-index-fat-types.rs create mode 100644 src/test/ui/tuple-index.rs create mode 100644 src/test/ui/tydesc-name.rs create mode 100644 src/test/ui/type-ascription.rs create mode 100644 src/test/ui/type-id-higher-rank-2.rs create mode 100644 src/test/ui/type-id-higher-rank.rs create mode 100644 src/test/ui/type-in-nested-module.rs create mode 100644 src/test/ui/type-infer-generalize-ty-var.rs create mode 100644 src/test/ui/type-namespace.rs create mode 100644 src/test/ui/type-param-constraints.rs create mode 100644 src/test/ui/type-param.rs create mode 100644 src/test/ui/type-params-in-for-each.rs create mode 100644 src/test/ui/type-ptr.rs create mode 100644 src/test/ui/type-sizes.rs create mode 100644 src/test/ui/type-use-i1-versus-i8.rs create mode 100644 src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs create mode 100644 src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs create mode 100644 src/test/ui/typeck_type_placeholder_1.rs create mode 100644 src/test/ui/typeclasses-eq-example-static.rs create mode 100644 src/test/ui/typeclasses-eq-example.rs create mode 100644 src/test/ui/typeid-intrinsic.rs create mode 100644 src/test/ui/typestate-cfg-nesting.rs create mode 100644 src/test/ui/typestate-multi-decl.rs create mode 100644 src/test/ui/ufcs-polymorphic-paths.rs create mode 100644 src/test/ui/ufcs-type-params.rs create mode 100644 src/test/ui/unary-minus-suffix-inference.rs create mode 100644 src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-boxed.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-drop.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-generic.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-prelude.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-simple.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs create mode 100644 src/test/ui/underscore-lifetimes.rs create mode 100644 src/test/ui/underscore-method-after-integer.rs create mode 100644 src/test/ui/uniform-paths/auxiliary/issue-53691.rs create mode 100644 src/test/ui/uniform-paths/basic-nested.rs create mode 100644 src/test/ui/uniform-paths/basic.rs create mode 100644 src/test/ui/uniform-paths/issue-53691.rs create mode 100644 src/test/ui/uniform-paths/macros-nested.rs create mode 100644 src/test/ui/uniform-paths/macros.rs create mode 100644 src/test/ui/uniform-paths/same-crate.rs create mode 100644 src/test/ui/unify-return-ty.rs create mode 100644 src/test/ui/uninit-empty-types.rs create mode 100644 src/test/ui/union/auxiliary/union.rs create mode 100644 src/test/ui/union/union-align.rs create mode 100644 src/test/ui/union/union-backcomp.rs create mode 100644 src/test/ui/union/union-basic.rs create mode 100644 src/test/ui/union/union-c-interop.rs create mode 100644 src/test/ui/union/union-const-codegen.rs create mode 100644 src/test/ui/union/union-const-eval-field.rs create mode 100644 src/test/ui/union/union-drop-assign.rs create mode 100644 src/test/ui/union/union-drop.rs create mode 100644 src/test/ui/union/union-inherent-method.rs create mode 100644 src/test/ui/union/union-macro.rs create mode 100644 src/test/ui/union/union-nodrop.rs create mode 100644 src/test/ui/union/union-nonzero.rs create mode 100644 src/test/ui/union/union-overwrite.rs create mode 100644 src/test/ui/union/union-packed.rs create mode 100644 src/test/ui/union/union-pat-refutability.rs create mode 100644 src/test/ui/union/union-trait-impl.rs create mode 100644 src/test/ui/union/union-transmute.rs create mode 100644 src/test/ui/unique/unique-assign-copy.rs create mode 100644 src/test/ui/unique/unique-assign-drop.rs create mode 100644 src/test/ui/unique/unique-assign-generic.rs create mode 100644 src/test/ui/unique/unique-assign.rs create mode 100644 src/test/ui/unique/unique-autoderef-field.rs create mode 100644 src/test/ui/unique/unique-autoderef-index.rs create mode 100644 src/test/ui/unique/unique-cmp.rs create mode 100644 src/test/ui/unique/unique-containing-tag.rs create mode 100644 src/test/ui/unique/unique-create.rs create mode 100644 src/test/ui/unique/unique-decl-init-copy.rs create mode 100644 src/test/ui/unique/unique-decl-init.rs create mode 100644 src/test/ui/unique/unique-decl-move.rs create mode 100644 src/test/ui/unique/unique-decl.rs create mode 100644 src/test/ui/unique/unique-deref.rs create mode 100644 src/test/ui/unique/unique-destructure.rs create mode 100644 src/test/ui/unique/unique-drop-complex.rs create mode 100644 src/test/ui/unique/unique-ffi-symbols.rs create mode 100644 src/test/ui/unique/unique-fn-arg-move.rs create mode 100644 src/test/ui/unique/unique-fn-arg-mut.rs create mode 100644 src/test/ui/unique/unique-fn-arg.rs create mode 100644 src/test/ui/unique/unique-fn-ret.rs create mode 100644 src/test/ui/unique/unique-generic-assign.rs create mode 100644 src/test/ui/unique/unique-in-tag.rs create mode 100644 src/test/ui/unique/unique-in-vec-copy.rs create mode 100644 src/test/ui/unique/unique-in-vec.rs create mode 100644 src/test/ui/unique/unique-init.rs create mode 100644 src/test/ui/unique/unique-kinds.rs create mode 100644 src/test/ui/unique/unique-log.rs create mode 100644 src/test/ui/unique/unique-match-discrim.rs create mode 100644 src/test/ui/unique/unique-move-drop.rs create mode 100644 src/test/ui/unique/unique-move-temp.rs create mode 100644 src/test/ui/unique/unique-move.rs create mode 100644 src/test/ui/unique/unique-mutable.rs create mode 100644 src/test/ui/unique/unique-object-move.rs create mode 100644 src/test/ui/unique/unique-pat-2.rs create mode 100644 src/test/ui/unique/unique-pat-3.rs create mode 100644 src/test/ui/unique/unique-pat.rs create mode 100644 src/test/ui/unique/unique-rec.rs create mode 100644 src/test/ui/unique/unique-send-2.rs create mode 100644 src/test/ui/unique/unique-send.rs create mode 100644 src/test/ui/unique/unique-swap.rs create mode 100644 src/test/ui/unit.rs create mode 100644 src/test/ui/unnamed_argument_mode.rs create mode 100644 src/test/ui/unreachable-code-1.rs create mode 100644 src/test/ui/unreachable-code.rs create mode 100644 src/test/ui/unsafe-coercion.rs create mode 100644 src/test/ui/unsafe-fn-called-from-unsafe-blk.rs create mode 100644 src/test/ui/unsafe-fn-called-from-unsafe-fn.rs create mode 100644 src/test/ui/unsafe-pointer-assignability.rs create mode 100644 src/test/ui/unsized-locals/autoderef.rs create mode 100644 src/test/ui/unsized-locals/box-fnonce.rs create mode 100644 src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs create mode 100644 src/test/ui/unsized-locals/reference-unsized-locals.rs create mode 100644 src/test/ui/unsized-locals/simple-unsized-locals.rs create mode 100644 src/test/ui/unsized-locals/unsized-parameters.rs create mode 100644 src/test/ui/unsized-tuple-impls.rs create mode 100644 src/test/ui/unsized.rs create mode 100644 src/test/ui/unsized2.rs create mode 100644 src/test/ui/unused-move-capture.rs create mode 100644 src/test/ui/unused-move.rs create mode 100644 src/test/ui/unwind-resource.rs create mode 100644 src/test/ui/unwind-unique.rs create mode 100644 src/test/ui/use-crate-name-alias.rs create mode 100644 src/test/ui/use-import-export.rs create mode 100644 src/test/ui/use-keyword-2.rs create mode 100644 src/test/ui/use-mod.rs create mode 100644 src/test/ui/use-nested-groups.rs create mode 100644 src/test/ui/use.rs create mode 100644 src/test/ui/use_inline_dtor.rs create mode 100644 src/test/ui/using-target-feature-unstable.rs create mode 100644 src/test/ui/utf8-bom.rs create mode 100644 src/test/ui/utf8.rs create mode 100644 src/test/ui/utf8_chars.rs create mode 100644 src/test/ui/variadic-ffi.rs create mode 100644 src/test/ui/variance-intersection-of-ref-and-opt-ref.rs create mode 100644 src/test/ui/variance-iterators-in-libcore.rs create mode 100644 src/test/ui/volatile-fat-ptr.rs create mode 100644 src/test/ui/wait-forked-but-failed-child.rs create mode 100644 src/test/ui/warn-ctypes-inhibit.rs create mode 100644 src/test/ui/weak-lang-item.rs create mode 100644 src/test/ui/weak-new-uninhabited-issue-48493.rs create mode 100644 src/test/ui/weird-exit-code.rs create mode 100644 src/test/ui/weird-exprs.rs create mode 100644 src/test/ui/wf-bound-region-in-object-type.rs create mode 100644 src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs create mode 100644 src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs create mode 100644 src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs create mode 100644 src/test/ui/where-clauses/where-clause-region-outlives.rs create mode 100644 src/test/ui/where-clauses/where-clauses-cross-crate.rs create mode 100644 src/test/ui/where-clauses/where-clauses-lifetimes.rs create mode 100644 src/test/ui/where-clauses/where-clauses-method.rs create mode 100644 src/test/ui/where-clauses/where-clauses-unboxed-closures.rs create mode 100644 src/test/ui/where-clauses/where-clauses.rs create mode 100644 src/test/ui/wrapping-int-api.rs create mode 100644 src/test/ui/write-fmt-errors.rs create mode 100644 src/test/ui/writealias.rs create mode 100644 src/test/ui/wrong-hashset-issue-42918.rs create mode 100644 src/test/ui/x86stdcall.rs create mode 100644 src/test/ui/x86stdcall2.rs create mode 100644 src/test/ui/yield.rs create mode 100644 src/test/ui/yield1.rs create mode 100644 src/test/ui/yield2.rs create mode 100644 src/test/ui/z-crate-attr.rs create mode 100644 src/test/ui/zero-sized/zero-size-type-destructors.rs create mode 100644 src/test/ui/zero-sized/zero-sized-binary-heap-push.rs create mode 100644 src/test/ui/zero-sized/zero-sized-btreemap-insert.rs create mode 100644 src/test/ui/zero-sized/zero-sized-linkedlist-push.rs create mode 100644 src/test/ui/zero-sized/zero-sized-tuple-struct.rs create mode 100644 src/test/ui/zero-sized/zero-sized-vec-deque-push.rs create mode 100644 src/test/ui/zero-sized/zero-sized-vec-push.rs (limited to 'src') diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs deleted file mode 100644 index c90fe001432..00000000000 --- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs +++ /dev/null @@ -1,304 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -// ignore-cross-compile - -#![feature(rustc_private)] - -extern crate syntax; - -use syntax::ast::*; -use syntax::attr::*; -use syntax::ast; -use syntax::source_map::{FilePathMapping, FileName}; -use syntax::parse; -use syntax::parse::{ParseSess, PResult}; -use syntax::parse::new_parser_from_source_str; -use syntax::parse::parser::Parser; -use syntax::parse::token; -use syntax::ptr::P; -use syntax::parse::attr::*; -use syntax::print::pprust; -use std::fmt; - -// Copied out of syntax::util::parser_testing - -pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> { - new_parser_from_source_str(ps, FileName::Custom(source_str.clone()), source_str) -} - -fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where - F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>, -{ - let mut p = string_to_parser(&ps, s); - let x = f(&mut p); - - if ps.span_diagnostic.has_errors() || p.token != token::Eof { - if let Err(mut e) = x { - e.cancel(); - } - return Err(p.fatal("parse error")); - } - - x -} - -fn expr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P> { - with_error_checking_parse(s.to_string(), ps, |p| { - p.parse_expr() - }) -} - -fn stmt<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Stmt> { - with_error_checking_parse(s.to_string(), ps, |p| { - p.parse_stmt().map(|s| s.unwrap()) - }) -} - -fn attr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Attribute> { - with_error_checking_parse(s.to_string(), ps, |p| { - p.parse_attribute(true) - }) -} - -fn str_compare String>(e: &str, expected: &[T], actual: &[T], f: F) { - let expected: Vec<_> = expected.iter().map(|e| f(e)).collect(); - let actual: Vec<_> = actual.iter().map(|e| f(e)).collect(); - - if expected != actual { - panic!("parsed `{}` as {:?}, expected {:?}", e, actual, expected); - } -} - -fn check_expr_attrs(es: &str, expected: &[&str]) { - let ps = ParseSess::new(FilePathMapping::empty()); - let e = expr(es, &ps).expect("parse error"); - let actual = &e.attrs; - str_compare(es, - &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::>(), - &actual, - pprust::attribute_to_string); -} - -fn check_stmt_attrs(es: &str, expected: &[&str]) { - let ps = ParseSess::new(FilePathMapping::empty()); - let e = stmt(es, &ps).expect("parse error"); - let actual = e.node.attrs(); - str_compare(es, - &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::>(), - actual, - pprust::attribute_to_string); -} - -fn reject_expr_parse(es: &str) { - let ps = ParseSess::new(FilePathMapping::empty()); - match expr(es, &ps) { - Ok(_) => panic!("parser did not reject `{}`", es), - Err(mut e) => e.cancel(), - }; -} - -fn reject_stmt_parse(es: &str) { - let ps = ParseSess::new(FilePathMapping::empty()); - match stmt(es, &ps) { - Ok(_) => panic!("parser did not reject `{}`", es), - Err(mut e) => e.cancel(), - }; -} - -fn main() { - syntax::with_default_globals(|| run()); -} - -fn run() { - let both = &["#[attr]", "#![attr]"]; - let outer = &["#[attr]"]; - let none = &[]; - - check_expr_attrs("#[attr] box 0", outer); - reject_expr_parse("box #![attr] 0"); - - check_expr_attrs("#[attr] [#![attr]]", both); - check_expr_attrs("#[attr] [#![attr] 0]", both); - check_expr_attrs("#[attr] [#![attr] 0; 0]", both); - check_expr_attrs("#[attr] [#![attr] 0, 0, 0]", both); - reject_expr_parse("[#[attr]]"); - - check_expr_attrs("#[attr] foo()", outer); - check_expr_attrs("#[attr] x.foo()", outer); - reject_expr_parse("foo#[attr]()"); - reject_expr_parse("foo(#![attr])"); - reject_expr_parse("x.foo(#![attr])"); - reject_expr_parse("x.#[attr]foo()"); - reject_expr_parse("x.#![attr]foo()"); - - check_expr_attrs("#[attr] (#![attr])", both); - check_expr_attrs("#[attr] (#![attr] #[attr] 0,)", both); - check_expr_attrs("#[attr] (#![attr] #[attr] 0, 0)", both); - - check_expr_attrs("#[attr] 0 + #[attr] 0", none); - check_expr_attrs("#[attr] 0 / #[attr] 0", none); - check_expr_attrs("#[attr] 0 & #[attr] 0", none); - check_expr_attrs("#[attr] 0 % #[attr] 0", none); - check_expr_attrs("#[attr] (0 + 0)", outer); - reject_expr_parse("0 + #![attr] 0"); - - check_expr_attrs("#[attr] !0", outer); - check_expr_attrs("#[attr] -0", outer); - reject_expr_parse("!#![attr] 0"); - reject_expr_parse("-#![attr] 0"); - - check_expr_attrs("#[attr] false", outer); - check_expr_attrs("#[attr] 0", outer); - check_expr_attrs("#[attr] 'c'", outer); - - check_expr_attrs("#[attr] x as Y", none); - check_expr_attrs("#[attr] (x as Y)", outer); - reject_expr_parse("x #![attr] as Y"); - - reject_expr_parse("#[attr] if false {}"); - reject_expr_parse("if false #[attr] {}"); - reject_expr_parse("if false {#![attr]}"); - reject_expr_parse("if false {} #[attr] else {}"); - reject_expr_parse("if false {} else #[attr] {}"); - reject_expr_parse("if false {} else {#![attr]}"); - reject_expr_parse("if false {} else #[attr] if true {}"); - reject_expr_parse("if false {} else if true #[attr] {}"); - reject_expr_parse("if false {} else if true {#![attr]}"); - - reject_expr_parse("#[attr] if let Some(false) = false {}"); - reject_expr_parse("if let Some(false) = false #[attr] {}"); - reject_expr_parse("if let Some(false) = false {#![attr]}"); - reject_expr_parse("if let Some(false) = false {} #[attr] else {}"); - reject_expr_parse("if let Some(false) = false {} else #[attr] {}"); - reject_expr_parse("if let Some(false) = false {} else {#![attr]}"); - reject_expr_parse("if let Some(false) = false {} else #[attr] if let Some(false) = true {}"); - reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true #[attr] {}"); - reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true {#![attr]}"); - - check_expr_attrs("#[attr] while true {#![attr]}", both); - - check_expr_attrs("#[attr] while let Some(false) = true {#![attr]}", both); - - check_expr_attrs("#[attr] for x in y {#![attr]}", both); - - check_expr_attrs("#[attr] loop {#![attr]}", both); - - check_expr_attrs("#[attr] match true {#![attr] #[attr] _ => false}", both); - - check_expr_attrs("#[attr] || #[attr] foo", outer); - check_expr_attrs("#[attr] move || #[attr] foo", outer); - check_expr_attrs("#[attr] || #[attr] { #![attr] foo }", outer); - check_expr_attrs("#[attr] move || #[attr] { #![attr] foo }", outer); - check_expr_attrs("#[attr] || { #![attr] foo }", outer); - check_expr_attrs("#[attr] move || { #![attr] foo }", outer); - reject_expr_parse("|| #![attr] foo"); - reject_expr_parse("move || #![attr] foo"); - reject_expr_parse("|| #![attr] {foo}"); - reject_expr_parse("move || #![attr] {foo}"); - - check_expr_attrs("#[attr] { #![attr] }", both); - check_expr_attrs("#[attr] { #![attr] let _ = (); }", both); - check_expr_attrs("#[attr] { #![attr] let _ = (); foo }", both); - - check_expr_attrs("#[attr] x = y", none); - check_expr_attrs("#[attr] (x = y)", outer); - - check_expr_attrs("#[attr] x += y", none); - check_expr_attrs("#[attr] (x += y)", outer); - - check_expr_attrs("#[attr] foo.bar", outer); - check_expr_attrs("(#[attr] foo).bar", none); - - check_expr_attrs("#[attr] foo.0", outer); - check_expr_attrs("(#[attr] foo).0", none); - - check_expr_attrs("#[attr] foo[bar]", outer); - check_expr_attrs("(#[attr] foo)[bar]", none); - - check_expr_attrs("#[attr] 0..#[attr] 0", none); - check_expr_attrs("#[attr] 0..", none); - reject_expr_parse("#[attr] ..#[attr] 0"); - reject_expr_parse("#[attr] .."); - - check_expr_attrs("#[attr] (0..0)", outer); - check_expr_attrs("#[attr] (0..)", outer); - check_expr_attrs("#[attr] (..0)", outer); - check_expr_attrs("#[attr] (..)", outer); - - check_expr_attrs("#[attr] foo::bar::baz", outer); - - check_expr_attrs("#[attr] &0", outer); - check_expr_attrs("#[attr] &mut 0", outer); - check_expr_attrs("#[attr] & #[attr] 0", outer); - check_expr_attrs("#[attr] &mut #[attr] 0", outer); - reject_expr_parse("#[attr] &#![attr] 0"); - reject_expr_parse("#[attr] &mut #![attr] 0"); - - check_expr_attrs("#[attr] break", outer); - check_expr_attrs("#[attr] continue", outer); - check_expr_attrs("#[attr] return", outer); - - check_expr_attrs("#[attr] foo!()", outer); - check_expr_attrs("#[attr] foo!(#![attr])", outer); - check_expr_attrs("#[attr] foo![]", outer); - check_expr_attrs("#[attr] foo![#![attr]]", outer); - check_expr_attrs("#[attr] foo!{}", outer); - check_expr_attrs("#[attr] foo!{#![attr]}", outer); - - check_expr_attrs("#[attr] Foo { #![attr] bar: baz }", both); - check_expr_attrs("#[attr] Foo { #![attr] ..foo }", both); - check_expr_attrs("#[attr] Foo { #![attr] bar: baz, ..foo }", both); - - check_expr_attrs("#[attr] (#![attr] 0)", both); - - // Look at statements in their natural habitat... - check_expr_attrs("{ - #[attr] let _ = 0; - #[attr] 0; - #[attr] foo!(); - #[attr] foo!{} - #[attr] foo![]; - }", none); - - check_stmt_attrs("#[attr] let _ = 0", outer); - check_stmt_attrs("#[attr] 0", outer); - check_stmt_attrs("#[attr] {#![attr]}", both); - check_stmt_attrs("#[attr] foo!()", outer); - check_stmt_attrs("#[attr] foo![]", outer); - check_stmt_attrs("#[attr] foo!{}", outer); - - reject_stmt_parse("#[attr] #![attr] let _ = 0"); - reject_stmt_parse("#[attr] #![attr] 0"); - reject_stmt_parse("#[attr] #![attr] foo!()"); - reject_stmt_parse("#[attr] #![attr] foo![]"); - reject_stmt_parse("#[attr] #![attr] foo!{}"); - - // FIXME: Allow attributes in pattern constexprs? - // note: requires parens in patterns to allow disambiguation - - reject_expr_parse("match 0 { - 0..=#[attr] 10 => () - }"); - reject_expr_parse("match 0 { - 0..=#[attr] -10 => () - }"); - reject_expr_parse("match 0 { - 0..=-#[attr] 10 => () - }"); - reject_expr_parse("match 0 { - 0..=#[attr] FOO => () - }"); - - // make sure we don't catch this bug again... - reject_expr_parse("{ - fn foo() { - #[attr]; - } - }"); - reject_expr_parse("{ - fn foo() { - #[attr] - } - }"); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs deleted file mode 100644 index c3a2ae679bf..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs +++ /dev/null @@ -1,3 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "dylib"] diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs deleted file mode 100644 index 39c261e1162..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs deleted file mode 100644 index e991bcc1a02..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -#[macro_use] #[no_link] extern crate issue_13560_1 as t1; -#[macro_use] extern crate issue_13560_2 as t2; diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-16822.rs b/src/test/run-pass-fulldeps/auxiliary/issue-16822.rs deleted file mode 100644 index 9042dd39117..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-16822.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![crate_type="lib"] - -use std::cell::RefCell; - -pub struct Window{ - pub data: RefCell -} - -impl Window { - pub fn update(&self, e: i32) { - match e { - 1 => self.data.borrow_mut().update(), - _ => {} - } - } -} - -pub trait Update { - fn update(&mut self); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-18502.rs b/src/test/run-pass-fulldeps/auxiliary/issue-18502.rs deleted file mode 100644 index 4d4230607aa..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-18502.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![crate_type="lib"] - -struct Foo; -// This is the ICE trigger -struct Formatter; - -trait Show { - fn fmt(&self); -} - -impl Show for Foo { - fn fmt(&self) {} -} - -fn bar(f: extern "Rust" fn(&T), t: &T) { } - -// ICE requirement: this has to be marked as inline -#[inline] -pub fn baz() { - bar(Show::fmt, &Foo); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs b/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs deleted file mode 100644 index 2c6a6034806..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![crate_type="lib"] - -enum E { E0 = 0, E1 = 1 } -const E0_U8: u8 = E::E0 as u8; -const E1_U8: u8 = E::E1 as u8; - -pub fn go() { - match 0 { - E0_U8 => (), - E1_U8 => (), - _ => (), - } -} diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs deleted file mode 100644 index ad42ee1d1ec..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![feature(box_syntax, plugin, plugin_registrar, rustc_private)] -#![crate_type = "dylib"] - -#[macro_use] -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; -extern crate syntax; - -use rustc_plugin::Registry; -use syntax::attr; -use syntax::ext::base::*; -use syntax::feature_gate::AttributeType::Whitelisted; -use syntax::symbol::Symbol; - -use rustc::hir; -use rustc::hir::intravisit; -use rustc::hir::map as hir_map; -use hir::Node; -use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use rustc::ty; -use syntax::{ast, source_map}; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box MissingWhitelistedAttrPass); - reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); -} - -declare_lint! { - MISSING_WHITELISTED_ATTR, - Deny, - "Checks for missing `whitelisted_attr` attribute" -} - -declare_lint_pass!(MissingWhitelistedAttrPass => [MISSING_WHITELISTED_ATTR]); - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass { - fn check_fn(&mut self, - cx: &LateContext<'a, 'tcx>, - _: intravisit::FnKind<'tcx>, - _: &'tcx hir::FnDecl, - _: &'tcx hir::Body, - span: source_map::Span, - id: hir::HirId) { - - let item = match cx.tcx.hir().get(id) { - Node::Item(item) => item, - _ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(id)), - }; - - if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) { - cx.span_lint(MISSING_WHITELISTED_ATTR, span, - "Missing 'whitelisted_attr' attribute"); - } - } -} diff --git a/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs b/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs deleted file mode 100644 index 8917693d45e..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs +++ /dev/null @@ -1,37 +0,0 @@ -// ignore-musl - dlsym doesn't see symbols without "-C link-arg=-Wl,--export-dynamic" - -#![feature(rustc_private)] - -// We're testing linkage visibility; the compiler warns us, but we want to -// do the runtime check that these functions aren't exported. -#![allow(private_no_mangle_fns)] - -extern crate rustc_metadata; - -use rustc_metadata::dynamic_lib::DynamicLibrary; - -#[no_mangle] -pub fn foo() { bar(); } - -pub fn foo2() { - fn bar2() { - bar(); - } - bar2(); -} - -#[no_mangle] -fn bar() { } - -#[allow(dead_code)] -#[no_mangle] -fn baz() { } - -pub fn test() { - let lib = DynamicLibrary::open(None).unwrap(); - unsafe { - assert!(lib.symbol::("foo").is_ok()); - assert!(lib.symbol::("baz").is_ok()); - assert!(lib.symbol::("bar").is_ok()); - } -} diff --git a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs deleted file mode 100644 index 2826ae75bee..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs +++ /dev/null @@ -1,74 +0,0 @@ -// force-host - -#![feature(plugin_registrar, rustc_private)] -#![feature(box_syntax)] - -#[macro_use] extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; -extern crate syntax; - -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; -use rustc_plugin::Registry; -use rustc::hir; -use syntax::attr; -use syntax::symbol::Symbol; - -macro_rules! fake_lint_pass { - ($struct:ident, $lints:expr, $($attr:expr),*) => { - struct $struct; - - impl LintPass for $struct { - fn name(&self) -> &'static str { - stringify!($struct) - } - - fn get_lints(&self) -> LintArray { - $lints - } - } - - impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { - fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { - $( - if !attr::contains_name(&krate.attrs, $attr) { - cx.span_lint(CRATE_NOT_OKAY, krate.span, - &format!("crate is not marked with #![{}]", $attr)); - } - )* - } - } - - } -} - -declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); -declare_lint!(CRATE_NOT_RED, Warn, "crate not marked with #![crate_red]"); -declare_lint!(CRATE_NOT_BLUE, Warn, "crate not marked with #![crate_blue]"); -declare_lint!(CRATE_NOT_GREY, Warn, "crate not marked with #![crate_grey]"); -declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); - -fake_lint_pass! { - PassOkay, - lint_array!(CRATE_NOT_OKAY), // Single lint - Symbol::intern("rustc_crate_okay") -} - -fake_lint_pass! { - PassRedBlue, - lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints - Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") -} - -fake_lint_pass! { - PassGreyGreen, - lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma - Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") -} - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box PassOkay); - reg.register_late_lint_pass(box PassRedBlue); - reg.register_late_lint_pass(box PassGreyGreen); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs deleted file mode 100644 index 1832fee4347..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs +++ /dev/null @@ -1,20 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(rustc_private)] - -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; - -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - // This pass is built in to LLVM. - // - // Normally, we would name a pass that was registered through - // C++ static object constructors in the same .so file as the - // plugin registrar. - reg.register_llvm_pass("gvn"); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs b/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs deleted file mode 100644 index 954a1e554da..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -pub fn foo() {} diff --git a/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs deleted file mode 100644 index 6e446241d55..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(rustc_private)] - -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; - -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(_reg: &mut Registry) {} diff --git a/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs b/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs deleted file mode 100644 index d9b2740e476..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs +++ /dev/null @@ -1,35 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![feature(rustc_private)] - -extern crate syntax; -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; -extern crate syntax_pos; -extern crate proc_macro; - -use proc_macro::{TokenTree, TokenStream}; - -#[proc_macro_attribute] -pub fn rustc_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/src/test/run-pass-fulldeps/auxiliary/outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/auxiliary/outlive-expansion-phase.rs deleted file mode 100644 index c22605afd0c..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/outlive-expansion-phase.rs +++ /dev/null @@ -1,26 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax, rustc_private)] - -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; - -use std::any::Any; -use std::cell::RefCell; -use rustc_plugin::Registry; - -struct Foo { - foo: isize -} - -impl Drop for Foo { - fn drop(&mut self) {} -} - -#[plugin_registrar] -pub fn registrar(_: &mut Registry) { - thread_local!(static FOO: RefCell>> = RefCell::new(None)); - FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box)); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs deleted file mode 100644 index 36cee82893a..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ /dev/null @@ -1,44 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; - -use std::borrow::ToOwned; -use syntax::ast; -use syntax::ext::build::AstBuilder; -use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; -use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager}; -use syntax::print::pprust; -use syntax::symbol::Symbol; -use syntax_pos::Span; -use syntax::tokenstream::TokenStream; -use rustc_plugin::Registry; - -struct Expander { - args: Vec, -} - -impl TTMacroExpander for Expander { - fn expand<'cx>(&self, - ecx: &'cx mut ExtCtxt, - sp: Span, - _: TokenStream) -> Box { - let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) - .collect::>().join(", "); - MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) - } -} - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - let args = reg.args().to_owned(); - reg.register_syntax_extension(Symbol::intern("plugin_args"), SyntaxExtension::default( - SyntaxExtensionKind::LegacyBang(Box::new(Expander { args })), reg.sess.edition() - )); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs deleted file mode 100644 index 07302b6e68b..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs +++ /dev/null @@ -1,70 +0,0 @@ -// WARNING WARNING WARNING WARNING WARNING -// ======================================= -// -// This code also appears in src/doc/unstable-book/src/language-features/plugin.md. -// Please keep the two copies in sync! FIXME: have rustdoc read this file - -// force-host - -#![crate_type="dylib"] -#![feature(plugin_registrar, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; -extern crate rustc_driver; - -use syntax::parse::token::{self, Token}; -use syntax::tokenstream::TokenTree; -use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; -use syntax::ext::build::AstBuilder; // A trait for expr_usize. -use syntax_pos::Span; -use rustc_plugin::Registry; - -fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) - -> Box { - - static NUMERALS: &'static [(&'static str, usize)] = &[ - ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), - ("C", 100), ("XC", 90), ("L", 50), ("XL", 40), - ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), - ("I", 1)]; - - if args.len() != 1 { - cx.span_err( - sp, - &format!("argument should be a single identifier, but got {} arguments", args.len())); - return DummyResult::any(sp); - } - - let text = match args[0] { - TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(), - _ => { - cx.span_err(sp, "argument should be a single identifier"); - return DummyResult::any(sp); - } - }; - - let mut text = &*text; - let mut total = 0; - while !text.is_empty() { - match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) { - Some(&(rn, val)) => { - total += val; - text = &text[rn.len()..]; - } - None => { - cx.span_err(sp, "invalid Roman numeral"); - return DummyResult::any(sp); - } - } - } - - MacEager::expr(cx.expr_usize(sp, total)) -} - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("rn", expand_rn); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs b/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs deleted file mode 100644 index 8b00fb81cd2..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs +++ /dev/null @@ -1,7 +0,0 @@ -// force-host - -#![crate_type = "dylib"] - -pub fn the_answer() -> isize { - 2 -} diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs deleted file mode 100644 index ea24f5809d5..00000000000 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -// Test that the Callbacks interface to the compiler works. - -// ignore-cross-compile -// ignore-stage1 - -#![feature(rustc_private)] - -extern crate rustc_driver; -extern crate rustc_interface; - -use rustc_interface::interface; - -struct TestCalls<'a> { - count: &'a mut u32 -} - -impl rustc_driver::Callbacks for TestCalls<'_> { - fn config(&mut self, _config: &mut interface::Config) { - *self.count *= 2; - } -} - -fn main() { - let mut count = 1; - let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()]; - rustc_driver::report_ices_to_stderr_if_any(|| { - rustc_driver::run_compiler(&args, &mut TestCalls { count: &mut count }, None, None).ok(); - }).ok(); - assert_eq!(count, 2); -} diff --git a/src/test/run-pass-fulldeps/create-dir-all-bare.rs b/src/test/run-pass-fulldeps/create-dir-all-bare.rs deleted file mode 100644 index 4554680ec24..00000000000 --- a/src/test/run-pass-fulldeps/create-dir-all-bare.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -use std::env; -use std::fs; -use std::path::PathBuf; - -fn main() { - let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - env::set_current_dir(&path).unwrap(); - fs::create_dir_all("create-dir-all-bare").unwrap(); -} diff --git a/src/test/run-pass-fulldeps/derive-no-std-not-supported.rs b/src/test/run-pass-fulldeps/derive-no-std-not-supported.rs deleted file mode 100644 index d09b1922a7b..00000000000 --- a/src/test/run-pass-fulldeps/derive-no-std-not-supported.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![feature(rustc_private)] -#![no_std] - -extern crate serialize as rustc_serialize; - -#[derive(RustcEncodable)] -struct Bar { - x: u32, -} - -#[derive(RustcDecodable)] -struct Baz { - x: u32, -} - -fn main() { - Bar { x: 0 }; - Baz { x: 0 }; -} diff --git a/src/test/run-pass-fulldeps/deriving-encodable-decodable-box.rs b/src/test/run-pass-fulldeps/deriving-encodable-decodable-box.rs deleted file mode 100644 index 877fb57a251..00000000000 --- a/src/test/run-pass-fulldeps/deriving-encodable-decodable-box.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - -#![allow(unused_imports)] - -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate serialize; -use serialize as rustc_serialize; - -use serialize::{Encodable, Decodable}; -use serialize::json; - -#[derive(RustcEncodable, RustcDecodable)] -struct A { - foo: Box<[bool]>, -} - -fn main() { - let obj = A { foo: Box::new([true, false]) }; - let s = json::encode(&obj).unwrap(); - let obj2: A = json::decode(&s).unwrap(); - assert_eq!(obj.foo, obj2.foo); -} diff --git a/src/test/run-pass-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass-fulldeps/deriving-encodable-decodable-cell-refcell.rs deleted file mode 100644 index a35b681641a..00000000000 --- a/src/test/run-pass-fulldeps/deriving-encodable-decodable-cell-refcell.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -// This briefly tests the capability of `Cell` and `RefCell` to implement the -// `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]` - - -#![feature(rustc_private)] - -extern crate serialize; -use serialize as rustc_serialize; - -use std::cell::{Cell, RefCell}; -use serialize::{Encodable, Decodable}; -use serialize::json; - -#[derive(RustcEncodable, RustcDecodable)] -struct A { - baz: isize -} - -#[derive(RustcEncodable, RustcDecodable)] -struct B { - foo: Cell, - bar: RefCell, -} - -fn main() { - let obj = B { - foo: Cell::new(true), - bar: RefCell::new( A { baz: 2 } ) - }; - let s = json::encode(&obj).unwrap(); - let obj2: B = json::decode(&s).unwrap(); - assert_eq!(obj.foo.get(), obj2.foo.get()); - assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz); -} diff --git a/src/test/run-pass-fulldeps/deriving-global.rs b/src/test/run-pass-fulldeps/deriving-global.rs deleted file mode 100644 index b59d55ff213..00000000000 --- a/src/test/run-pass-fulldeps/deriving-global.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass - -#![feature(rustc_private)] - -extern crate serialize; -use serialize as rustc_serialize; - -mod submod { - // if any of these are implemented without global calls for any - // function calls, then being in a submodule will (correctly) - // cause errors about unrecognised module `std` (or `extra`) - #[derive(PartialEq, PartialOrd, Eq, Ord, - Hash, - Clone, - Debug, - RustcEncodable, RustcDecodable)] - enum A { A1(usize), A2(isize) } - - #[derive(PartialEq, PartialOrd, Eq, Ord, - Hash, - Clone, - Debug, - RustcEncodable, RustcDecodable)] - struct B { x: usize, y: isize } - - #[derive(PartialEq, PartialOrd, Eq, Ord, - Hash, - Clone, - Debug, - RustcEncodable, RustcDecodable)] - struct C(usize, isize); - -} - -pub fn main() {} diff --git a/src/test/run-pass-fulldeps/deriving-hygiene.rs b/src/test/run-pass-fulldeps/deriving-hygiene.rs deleted file mode 100644 index 0d7439ef872..00000000000 --- a/src/test/run-pass-fulldeps/deriving-hygiene.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -#![allow(non_upper_case_globals)] -#![feature(rustc_private)] -extern crate serialize; -use serialize as rustc_serialize; - -pub const other: u8 = 1; -pub const f: u8 = 1; -pub const d: u8 = 1; -pub const s: u8 = 1; -pub const state: u8 = 1; -pub const cmp: u8 = 1; - -#[derive(Ord,Eq,PartialOrd,PartialEq,Debug,RustcDecodable,RustcEncodable,Hash)] -struct Foo {} - -fn main() { -} diff --git a/src/test/run-pass-fulldeps/dropck_tarena_sound_drop.rs b/src/test/run-pass-fulldeps/dropck_tarena_sound_drop.rs deleted file mode 100644 index cf188d9efa3..00000000000 --- a/src/test/run-pass-fulldeps/dropck_tarena_sound_drop.rs +++ /dev/null @@ -1,43 +0,0 @@ -// run-pass - -#![allow(unknown_lints)] -// Check that an arena (TypedArena) can carry elements whose drop -// methods might access borrowed data, as long as the borrowed data -// has lifetime that strictly outlives the arena itself. -// -// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which -// shows a similar setup, but restricts `f` so that the struct `C<'a>` -// is force-fed a lifetime equal to that of the borrowed arena. - -#![allow(unstable)] -#![feature(rustc_private)] - -extern crate arena; - -use arena::TypedArena; - -trait HasId { fn count(&self) -> usize; } - -struct CheckId { v: T } - -// In the code below, the impl of HasId for `&'a usize` does not -// actually access the borrowed data, but the point is that the -// interface to CheckId does not (and cannot) know that, and therefore -// when encountering a value V of type CheckId, we must -// conservatively force the type S to strictly outlive V. -impl Drop for CheckId { - fn drop(&mut self) { - assert!(self.v.count() > 0); - } -} - -struct C<'a> { _v: CheckId<&'a usize>, } - -impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } } - -fn f<'a, 'b>(_arena: &'a TypedArena>) {} - -fn main() { - let arena: TypedArena = TypedArena::default(); - f(&arena); -} diff --git a/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs b/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs deleted file mode 100644 index 68b407423aa..00000000000 --- a/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs +++ /dev/null @@ -1,56 +0,0 @@ -// run-pass -// `#[derive(Trait)]` works for empty structs/variants with braces or parens. - -#![feature(rustc_private)] - -extern crate serialize as rustc_serialize; - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, - Default, Debug, RustcEncodable, RustcDecodable)] -struct S {} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, - Default, Debug, RustcEncodable, RustcDecodable)] -struct Z(); - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, - Debug, RustcEncodable, RustcDecodable)] -enum E { - V {}, - U, - W(), -} - -fn main() { - let s = S {}; - let s1 = s; - let s2 = s.clone(); - assert_eq!(s, s1); - assert_eq!(s, s2); - assert!(!(s < s1)); - assert_eq!(format!("{:?}", s), "S"); - - let z = Z(); - let z1 = z; - let z2 = z.clone(); - assert_eq!(z, z1); - assert_eq!(z, z2); - assert!(!(z < z1)); - assert_eq!(format!("{:?}", z), "Z"); - - let e = E::V {}; - let e1 = e; - let e2 = e.clone(); - assert_eq!(e, e1); - assert_eq!(e, e2); - assert!(!(e < e1)); - assert_eq!(format!("{:?}", e), "V"); - - let e = E::W(); - let e1 = e; - let e2 = e.clone(); - assert_eq!(e, e1); - assert_eq!(e, e2); - assert!(!(e < e1)); - assert_eq!(format!("{:?}", e), "W"); -} diff --git a/src/test/run-pass-fulldeps/extern-mod-syntax.rs b/src/test/run-pass-fulldeps/extern-mod-syntax.rs deleted file mode 100644 index 258ab0dbe95..00000000000 --- a/src/test/run-pass-fulldeps/extern-mod-syntax.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -#![feature(rustc_private)] - -extern crate serialize; -use serialize::json::Object; - -pub fn main() { - println!("Hello world!"); -} diff --git a/src/test/run-pass-fulldeps/issue-11881.rs b/src/test/run-pass-fulldeps/issue-11881.rs deleted file mode 100644 index c8893e62941..00000000000 --- a/src/test/run-pass-fulldeps/issue-11881.rs +++ /dev/null @@ -1,52 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(dead_code)] -#![allow(unused_imports)] - -#![feature(rustc_private)] - -extern crate serialize; -use serialize as rustc_serialize; - -use std::io::Cursor; -use std::io::prelude::*; -use std::fmt; -use std::slice; - -use serialize::{Encodable, Encoder}; -use serialize::json; -use serialize::opaque; - -#[derive(RustcEncodable)] -struct Foo { - baz: bool, -} - -#[derive(RustcEncodable)] -struct Bar { - froboz: usize, -} - -enum WireProtocol { - JSON, - Opaque, - // ... -} - -fn encode_json(val: &T, wr: &mut Cursor>) { - write!(wr, "{}", json::as_json(val)); -} -fn encode_opaque(val: &T, wr: Vec) { - let mut encoder = opaque::Encoder::new(wr); - val.encode(&mut encoder); -} - -pub fn main() { - let target = Foo{baz: false,}; - let proto = WireProtocol::JSON; - match proto { - WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())), - WireProtocol::Opaque => encode_opaque(&target, Vec::new()) - } -} diff --git a/src/test/run-pass-fulldeps/issue-13560.rs b/src/test/run-pass-fulldeps/issue-13560.rs deleted file mode 100644 index 5f7d647e230..00000000000 --- a/src/test/run-pass-fulldeps/issue-13560.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// aux-build:issue-13560-1.rs -// aux-build:issue-13560-2.rs -// aux-build:issue-13560-3.rs - -// Regression test for issue #13560, the test itself is all in the dependent -// libraries. The fail which previously failed to compile is the one numbered 3. - -extern crate issue_13560_2 as t2; -extern crate issue_13560_3 as t3; - -fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-14021.rs b/src/test/run-pass-fulldeps/issue-14021.rs deleted file mode 100644 index 49fa4492fa1..00000000000 --- a/src/test/run-pass-fulldeps/issue-14021.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass - -#![allow(unused_mut)] -#![allow(unused_imports)] -#![feature(rustc_private)] - -extern crate serialize; -extern crate serialize as rustc_serialize; - -use serialize::{Encodable, Decodable}; -use serialize::json; - -#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] -struct UnitLikeStruct; - -pub fn main() { - let obj = UnitLikeStruct; - let json_str: String = json::encode(&obj).unwrap(); - - let json_object = json::from_str(&json_str); - let mut decoder = json::Decoder::new(json_object.unwrap()); - let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder).unwrap(); - - assert_eq!(obj, decoded_obj); -} diff --git a/src/test/run-pass-fulldeps/issue-15149.rs b/src/test/run-pass-fulldeps/issue-15149.rs deleted file mode 100644 index c80628aabc8..00000000000 --- a/src/test/run-pass-fulldeps/issue-15149.rs +++ /dev/null @@ -1,56 +0,0 @@ -// run-pass - -#![allow(unused_variables)] -// no-prefer-dynamic -// ignore-cross-compile - -use std::env; -use std::fs; -use std::process; -use std::str; -use std::path::PathBuf; - -fn main() { - // If we're the child, make sure we were invoked correctly - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - // FIXME: This should check the whole `args[0]` instead of just - // checking that it ends_with the executable name. This - // is needed because of Windows, which has a different behavior. - // See #15149 for more info. - return assert!(args[0].ends_with(&format!("mytest{}", - env::consts::EXE_SUFFIX))); - } - - test(); -} - -fn test() { - // If we're the parent, copy our own binary to a new directory. - let my_path = env::current_exe().unwrap(); - let my_dir = my_path.parent().unwrap(); - - let child_dir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let child_dir = child_dir.join("issue-15140-child"); - fs::create_dir_all(&child_dir).unwrap(); - - let child_path = child_dir.join(&format!("mytest{}", - env::consts::EXE_SUFFIX)); - fs::copy(&my_path, &child_path).unwrap(); - - // Append the new directory to our own PATH. - let path = { - let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect(); - paths.push(child_dir.to_path_buf()); - env::join_paths(paths).unwrap() - }; - - let child_output = process::Command::new("mytest").env("PATH", &path) - .arg("child") - .output().unwrap(); - - assert!(child_output.status.success(), - format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - str::from_utf8(&child_output.stdout).unwrap(), - str::from_utf8(&child_output.stderr).unwrap())); -} diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs deleted file mode 100644 index 91cf5dde0fb..00000000000 --- a/src/test/run-pass-fulldeps/issue-15778-pass.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// aux-build:lint-for-crate.rs -// ignore-stage1 -// compile-flags: -D crate-not-okay - -#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)] - -#![plugin(lint_for_crate)] -#![rustc_crate_okay] -#![rustc_crate_blue] -#![rustc_crate_red] -#![rustc_crate_grey] -#![rustc_crate_green] - -fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-15924.rs b/src/test/run-pass-fulldeps/issue-15924.rs deleted file mode 100644 index ec33de12ebb..00000000000 --- a/src/test/run-pass-fulldeps/issue-15924.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -#![allow(unused_must_use)] -// pretty-expanded FIXME #23616 - -#![feature(rustc_private)] - -extern crate serialize; - -use std::fmt; -use serialize::{Encoder, Encodable}; -use serialize::json; - -struct Foo { - v: T, -} - -impl Drop for Foo { - fn drop(&mut self) { - json::encode(&self.v); - } -} - -fn main() { - let _ = Foo { v: 10 }; -} diff --git a/src/test/run-pass-fulldeps/issue-16822.rs b/src/test/run-pass-fulldeps/issue-16822.rs deleted file mode 100644 index c611c33affd..00000000000 --- a/src/test/run-pass-fulldeps/issue-16822.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -// aux-build:issue-16822.rs - -extern crate issue_16822 as lib; - -use std::cell::RefCell; - -struct App { - i: isize -} - -impl lib::Update for App { - fn update(&mut self) { - self.i += 1; - } -} - -fn main(){ - let app = App { i: 5 }; - let window = lib::Window { data: RefCell::new(app) }; - window.update(1); -} diff --git a/src/test/run-pass-fulldeps/issue-18502.rs b/src/test/run-pass-fulldeps/issue-18502.rs deleted file mode 100644 index 2082ae7a991..00000000000 --- a/src/test/run-pass-fulldeps/issue-18502.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-18502.rs - -extern crate issue_18502 as fmt; - -fn main() { - ::fmt::baz(); -} diff --git a/src/test/run-pass-fulldeps/issue-24106.rs b/src/test/run-pass-fulldeps/issue-24106.rs deleted file mode 100644 index 45f0bd5b679..00000000000 --- a/src/test/run-pass-fulldeps/issue-24106.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-24106.rs - -extern crate issue_24106; - -fn main() { - issue_24106::go::<()>(); -} diff --git a/src/test/run-pass-fulldeps/issue-24972.rs b/src/test/run-pass-fulldeps/issue-24972.rs deleted file mode 100644 index 0d354aac137..00000000000 --- a/src/test/run-pass-fulldeps/issue-24972.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![feature(rustc_private)] - -extern crate serialize; - -use serialize::{Encodable, Decodable}; -use std::fmt::Display; - -pub trait Entity : Decodable + Encodable + Sized { - type Key: Clone + Decodable + Encodable + ToString + Display + Eq + Ord + Sized; - - fn id(&self) -> Self::Key; - - fn find_by_id(id: Self::Key) -> Option; -} - -pub struct DbRef { - pub id: E::Key, -} - -impl DbRef where E: Entity { - fn get(self) -> Option { - E::find_by_id(self.id) - } -} - -fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-2804.rs b/src/test/run-pass-fulldeps/issue-2804.rs deleted file mode 100644 index a5345bbcd14..00000000000 --- a/src/test/run-pass-fulldeps/issue-2804.rs +++ /dev/null @@ -1,70 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] -#![feature(rustc_private)] - -extern crate serialize; - -use std::collections::HashMap; -use serialize::json::{self, Json}; -use std::option; - -enum object { - bool_value(bool), - int_value(i64), -} - -fn lookup(table: json::Object, key: String, default: String) -> String -{ - match table.get(&key) { - option::Option::Some(&Json::String(ref s)) => { - s.to_string() - } - option::Option::Some(value) => { - println!("{} was expected to be a string but is a {}", key, value); - default - } - option::Option::None => { - default - } - } -} - -fn add_interface(_store: isize, managed_ip: String, data: json::Json) -> (String, object) -{ - match &data { - &Json::Object(ref interface) => { - let name = lookup(interface.clone(), - "ifDescr".to_string(), - "".to_string()); - let label = format!("{}-{}", managed_ip, name); - - (label, object::bool_value(false)) - } - _ => { - println!("Expected dict for {} interfaces, found {}", managed_ip, data); - ("gnos:missing-interface".to_string(), object::bool_value(true)) - } - } -} - -fn add_interfaces(store: isize, managed_ip: String, device: HashMap) --> Vec<(String, object)> { - match device["interfaces"] { - Json::Array(ref interfaces) => - { - interfaces.iter().map(|interface| { - add_interface(store, managed_ip.clone(), (*interface).clone()) - }).collect() - } - _ => - { - println!("Expected list for {} interfaces, found {}", managed_ip, - device["interfaces"]); - Vec::new() - } - } -} - -pub fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-40001.rs b/src/test/run-pass-fulldeps/issue-40001.rs deleted file mode 100644 index 65e188ed1b6..00000000000 --- a/src/test/run-pass-fulldeps/issue-40001.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// aux-build:issue-40001-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(issue_40001_plugin)] - -#[whitelisted_attr] -fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-4016.rs b/src/test/run-pass-fulldeps/issue-4016.rs deleted file mode 100644 index fb84acbe645..00000000000 --- a/src/test/run-pass-fulldeps/issue-4016.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass - -#![allow(dead_code)] - -#![feature(rustc_private)] - -extern crate serialize; - -use serialize::{json, Decodable}; - -trait JD : Decodable {} - -fn exec() { - let doc = json::from_str("").unwrap(); - let mut decoder = json::Decoder::new(doc); - let _v: T = Decodable::decode(&mut decoder).unwrap(); - panic!() -} - -pub fn main() {} diff --git a/src/test/run-pass-fulldeps/issue-4036.rs b/src/test/run-pass-fulldeps/issue-4036.rs deleted file mode 100644 index 9c9d3914268..00000000000 --- a/src/test/run-pass-fulldeps/issue-4036.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// Issue #4036: Test for an issue that arose around fixing up type inference -// byproducts in vtable records. - -// pretty-expanded FIXME #23616 - -#![feature(rustc_private)] - -extern crate serialize; - -use serialize::{json, Decodable}; - -pub fn main() { - let json = json::from_str("[1]").unwrap(); - let mut decoder = json::Decoder::new(json); - let _x: Vec = Decodable::decode(&mut decoder).unwrap(); -} diff --git a/src/test/run-pass-fulldeps/linkage-visibility.rs b/src/test/run-pass-fulldeps/linkage-visibility.rs deleted file mode 100644 index ae46fbc4e8a..00000000000 --- a/src/test/run-pass-fulldeps/linkage-visibility.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// aux-build:linkage-visibility.rs -// ignore-android: FIXME(#10356) -// ignore-windows: std::dynamic_lib does not work on Windows well -// ignore-emscripten no dynamic linking - -extern crate linkage_visibility as foo; - -pub fn main() { - foo::test(); - foo::foo2::(); - foo::foo(); -} diff --git a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs deleted file mode 100644 index a9b53fa8c74..00000000000 --- a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:llvm-pass-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(llvm_pass_plugin)] - -pub fn main() { } diff --git a/src/test/run-pass-fulldeps/lto-syntax-extension.rs b/src/test/run-pass-fulldeps/lto-syntax-extension.rs deleted file mode 100644 index 135861dd772..00000000000 --- a/src/test/run-pass-fulldeps/lto-syntax-extension.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// aux-build:lto-syntax-extension-lib.rs -// aux-build:lto-syntax-extension-plugin.rs -// compile-flags:-C lto -// ignore-stage1 -// no-prefer-dynamic - -#![feature(plugin)] -#![plugin(lto_syntax_extension_plugin)] - -extern crate lto_syntax_extension_lib; - -fn main() { - lto_syntax_extension_lib::foo(); -} diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs deleted file mode 100644 index e396cf01615..00000000000 --- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs +++ /dev/null @@ -1,49 +0,0 @@ -// run-pass - -#![allow(plugin_as_library)] -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] -// aux-build:macro-crate-test.rs -// ignore-stage1 - -#![feature(rustc_attrs)] - -#[macro_use] -extern crate macro_crate_test; - -// The duplicate macro will create a copy of the item with the given identifier. - -#[rustc_duplicate(MyCopy)] -struct MyStruct { - number: i32 -} - -trait TestTrait { - #[rustc_duplicate(TestType2)] - type TestType; - - #[rustc_duplicate(required_fn2)] - fn required_fn(&self); - - #[rustc_duplicate(provided_fn2)] - fn provided_fn(&self) { } -} - -impl TestTrait for MyStruct { - #[rustc_duplicate(TestType2)] - type TestType = f64; - - #[rustc_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/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs b/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs deleted file mode 100644 index 8631bcca6d2..00000000000 --- a/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass -// Testing that a libsyntax can parse modules with canonicalized base path -// ignore-cross-compile - -#![feature(rustc_private)] - -extern crate syntax; - -use std::path::Path; -use syntax::source_map::FilePathMapping; -use syntax::parse::{self, ParseSess}; - -#[path = "mod_dir_simple/test.rs"] -mod gravy; - -pub fn main() { - syntax::with_default_globals(|| parse()); - - assert_eq!(gravy::foo(), 10); -} - -fn parse() { - let parse_session = ParseSess::new(FilePathMapping::empty()); - - let path = Path::new(file!()); - let path = path.canonicalize().unwrap(); - let mut parser = parse::new_parser_from_file(&parse_session, &path); - let _ = parser.parse_crate_mod(); -} diff --git a/src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir b/src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass-fulldeps/mod_dir_simple/test.rs b/src/test/run-pass-fulldeps/mod_dir_simple/test.rs deleted file mode 100644 index 35e26093a2d..00000000000 --- a/src/test/run-pass-fulldeps/mod_dir_simple/test.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() -> isize { 10 } diff --git a/src/test/run-pass-fulldeps/myriad-closures.rs b/src/test/run-pass-fulldeps/myriad-closures.rs deleted file mode 100644 index 310351f50cb..00000000000 --- a/src/test/run-pass-fulldeps/myriad-closures.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass -// This test case tests whether we can handle code bases that contain a high -// number of closures, something that needs special handling in the MingGW -// toolchain. -// See https://github.com/rust-lang/rust/issues/34793 for more information. - -// Make sure we don't optimize anything away: -// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals - -// Expand something exponentially -macro_rules! go_bacterial { - ($mac:ident) => ($mac!()); - ($mac:ident 1 $($t:tt)*) => ( - go_bacterial!($mac $($t)*); - go_bacterial!($mac $($t)*); - ) -} - -macro_rules! mk_closure { - () => ((move || {})()) -} - -macro_rules! mk_fn { - () => { - { - fn function() { - // Make 16 closures - go_bacterial!(mk_closure 1 1 1 1); - } - let _ = function(); - } - } -} - -fn main() { - // Make 2^8 functions, each containing 16 closures, - // resulting in 2^12 closures overall. - go_bacterial!(mk_fn 1 1 1 1 1 1 1 1); -} diff --git a/src/test/run-pass-fulldeps/newtype_index.rs b/src/test/run-pass-fulldeps/newtype_index.rs deleted file mode 100644 index 336b584768f..00000000000 --- a/src/test/run-pass-fulldeps/newtype_index.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass - -#![feature(rustc_private)] - -extern crate rustc_data_structures; -extern crate serialize as rustc_serialize; - -use rustc_data_structures::{newtype_index, indexed_vec::Idx}; - -newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); - -use std::mem::size_of; - -fn main() { - assert_eq!(size_of::(), 4); - assert_eq!(size_of::>(), 4); - assert_eq!(size_of::>>(), 4); - assert_eq!(size_of::>>>(), 4); - assert_eq!(size_of::>>>>(), 4); - assert_eq!(size_of::>>>>>(), 4); - assert_eq!(size_of::>>>>>>(), 8); -} diff --git a/src/test/run-pass-fulldeps/outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/outlive-expansion-phase.rs deleted file mode 100644 index 752f1da7377..00000000000 --- a/src/test/run-pass-fulldeps/outlive-expansion-phase.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:outlive-expansion-phase.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(outlive_expansion_phase)] - -pub fn main() {} diff --git a/src/test/run-pass-fulldeps/plugin-args-1.rs b/src/test/run-pass-fulldeps/plugin-args-1.rs deleted file mode 100644 index d6437146775..00000000000 --- a/src/test/run-pass-fulldeps/plugin-args-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:plugin-args.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(plugin_args)] - -fn main() { - assert_eq!(plugin_args!(), ""); -} diff --git a/src/test/run-pass-fulldeps/plugin-args-2.rs b/src/test/run-pass-fulldeps/plugin-args-2.rs deleted file mode 100644 index 949f8440379..00000000000 --- a/src/test/run-pass-fulldeps/plugin-args-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:plugin-args.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(plugin_args())] - -fn main() { - assert_eq!(plugin_args!(), ""); -} diff --git a/src/test/run-pass-fulldeps/plugin-args-3.rs b/src/test/run-pass-fulldeps/plugin-args-3.rs deleted file mode 100644 index efdbcd0bf0d..00000000000 --- a/src/test/run-pass-fulldeps/plugin-args-3.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:plugin-args.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(plugin_args(hello(there), how(are="you")))] - -fn main() { - assert_eq!(plugin_args!(), "hello(there), how(are = \"you\")"); -} diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs deleted file mode 100644 index 09f58521e5d..00000000000 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ /dev/null @@ -1,230 +0,0 @@ -// run-pass -// ignore-cross-compile - -// The general idea of this test is to enumerate all "interesting" expressions and check that -// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: -// -// 1. The test focuses on expression nesting, because interactions between different expression -// types are harder to test manually than single expression types in isolation. -// -// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + -// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct -// handling of an expression might depend on the expression's parent, but doesn't depend on its -// siblings or any more distant ancestors. -// -// 3. The test only checks certain expression kinds. The assumption is that similar expression -// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer -// and parser. So if all combinations of exprs involving `if` work correctly, then combinations -// using `while`, `if let`, and so on will likely work as well. - -#![feature(rustc_private)] - -extern crate rustc_data_structures; -extern crate syntax; - -use rustc_data_structures::thin_vec::ThinVec; -use syntax::ast::*; -use syntax::source_map::{Spanned, DUMMY_SP, FileName}; -use syntax::source_map::FilePathMapping; -use syntax::mut_visit::{self, MutVisitor, visit_clobber}; -use syntax::parse::{self, ParseSess}; -use syntax::print::pprust; -use syntax::ptr::P; - - -fn parse_expr(ps: &ParseSess, src: &str) -> P { - let src_as_string = src.to_string(); - - let mut p = parse::new_parser_from_source_str(ps, - FileName::Custom(src_as_string.clone()), - src_as_string); - p.parse_expr().unwrap() -} - - -// Helper functions for building exprs -fn expr(kind: ExprKind) -> P { - P(Expr { - id: DUMMY_NODE_ID, - node: kind, - span: DUMMY_SP, - attrs: ThinVec::new(), - }) -} - -fn make_x() -> P { - let seg = PathSegment::from_ident(Ident::from_str("x")); - let path = Path { segments: vec![seg], span: DUMMY_SP }; - expr(ExprKind::Path(None, path)) -} - -/// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting" -/// combinations of expression nesting. For example, we explore combinations using `if`, but not -/// `while` or `match`, since those should print and parse in much the same way as `if`. -fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { - if depth == 0 { - f(make_x()); - return; - } - - let mut g = |e| f(expr(e)); - - for kind in 0..=19 { - match kind { - 0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))), - 1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))), - 2 => { - let seg = PathSegment::from_ident(Ident::from_str("x")); - iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( - seg.clone(), vec![e, make_x()]))); - iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( - seg.clone(), vec![make_x(), e]))); - }, - 3..=8 => { - let op = Spanned { - span: DUMMY_SP, - node: match kind { - 3 => BinOpKind::Add, - 4 => BinOpKind::Mul, - 5 => BinOpKind::Shl, - 6 => BinOpKind::And, - 7 => BinOpKind::Or, - 8 => BinOpKind::Lt, - _ => unreachable!(), - } - }; - iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x()))); - iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e))); - }, - 9 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e))); - }, - 10 => { - let block = P(Block { - stmts: Vec::new(), - id: DUMMY_NODE_ID, - rules: BlockCheckMode::Default, - span: DUMMY_SP, - }); - iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None))); - }, - 11 => { - let decl = P(FnDecl { - inputs: vec![], - output: FunctionRetTy::Default(DUMMY_SP), - c_variadic: false, - }); - iter_exprs(depth - 1, &mut |e| g( - ExprKind::Closure(CaptureBy::Value, - IsAsync::NotAsync, - Movability::Movable, - decl.clone(), - e, - DUMMY_SP))); - }, - 12 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x()))); - iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e))); - }, - 13 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f")))); - }, - 14 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::Range( - Some(e), Some(make_x()), RangeLimits::HalfOpen))); - iter_exprs(depth - 1, &mut |e| g(ExprKind::Range( - Some(make_x()), Some(e), RangeLimits::HalfOpen))); - }, - 15 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::AddrOf(Mutability::Immutable, e))); - }, - 16 => { - g(ExprKind::Ret(None)); - iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e)))); - }, - 17 => { - let path = Path::from_ident(Ident::from_str("S")); - g(ExprKind::Struct(path, vec![], Some(make_x()))); - }, - 18 => { - iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e))); - }, - 19 => { - let ps = vec![P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Wild, - span: DUMMY_SP, - })]; - iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(ps.clone(), e))) - }, - _ => panic!("bad counter value in iter_exprs"), - } - } -} - - -// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. - -/// `MutVisitor` that removes all `ExprKind::Paren` nodes. -struct RemoveParens; - -impl MutVisitor for RemoveParens { - fn visit_expr(&mut self, e: &mut P) { - match e.node.clone() { - ExprKind::Paren(inner) => *e = inner, - _ => {} - }; - mut_visit::noop_visit_expr(e, self); - } -} - - -/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`. -struct AddParens; - -impl MutVisitor for AddParens { - fn visit_expr(&mut self, e: &mut P) { - mut_visit::noop_visit_expr(e, self); - visit_clobber(e, |e| { - P(Expr { - id: DUMMY_NODE_ID, - node: ExprKind::Paren(e), - span: DUMMY_SP, - attrs: ThinVec::new(), - }) - }); - } -} - -fn main() { - syntax::with_default_globals(|| run()); -} - -fn run() { - let ps = ParseSess::new(FilePathMapping::empty()); - - iter_exprs(2, &mut |mut e| { - // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, - // modulo placement of `Paren` nodes. - let printed = pprust::expr_to_string(&e); - println!("printed: {}", printed); - - let mut parsed = parse_expr(&ps, &printed); - - // We want to know if `parsed` is structurally identical to `e`, ignoring trivial - // differences like placement of `Paren`s or the exact ranges of node spans. - // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s - // everywhere we can, then pretty-print. This should give an unambiguous representation of - // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't - // relying on the correctness of the very thing we're testing. - RemoveParens.visit_expr(&mut e); - AddParens.visit_expr(&mut e); - let text1 = pprust::expr_to_string(&e); - RemoveParens.visit_expr(&mut parsed); - AddParens.visit_expr(&mut parsed); - let text2 = pprust::expr_to_string(&parsed); - assert!(text1 == text2, - "exprs are not equal:\n e = {:?}\n parsed = {:?}", - text1, text2); - }); -} diff --git a/src/test/run-pass-fulldeps/regions-mock-tcx.rs b/src/test/run-pass-fulldeps/regions-mock-tcx.rs deleted file mode 100644 index 524c94a8555..00000000000 --- a/src/test/run-pass-fulldeps/regions-mock-tcx.rs +++ /dev/null @@ -1,134 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![allow(unused_imports)] - -// Test a sample usage pattern for regions. Makes use of the -// following features: -// -// - Multiple lifetime parameters -// - Arenas - -#![feature(rustc_private, libc)] - -extern crate arena; -extern crate libc; - -use TypeStructure::{TypeInt, TypeFunction}; -use AstKind::{ExprInt, ExprVar, ExprLambda}; -use arena::TypedArena; -use std::collections::HashMap; -use std::mem; - -type Type<'tcx> = &'tcx TypeStructure<'tcx>; - -#[derive(Copy, Clone, Debug)] -enum TypeStructure<'tcx> { - TypeInt, - TypeFunction(Type<'tcx>, Type<'tcx>), -} - -impl<'tcx> PartialEq for TypeStructure<'tcx> { - fn eq(&self, other: &TypeStructure<'tcx>) -> bool { - match (*self, *other) { - (TypeInt, TypeInt) => true, - (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b, - _ => false - } - } -} - -impl<'tcx> Eq for TypeStructure<'tcx> {} - -type TyArena<'tcx> = TypedArena>; -type AstArena<'ast> = TypedArena>; - -struct TypeContext<'tcx, 'ast> { - ty_arena: &'tcx TyArena<'tcx>, - types: Vec> , - type_table: HashMap>, - - ast_arena: &'ast AstArena<'ast>, - ast_counter: usize, -} - -impl<'tcx,'ast> TypeContext<'tcx, 'ast> { - fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>) - -> TypeContext<'tcx, 'ast> { - TypeContext { ty_arena: ty_arena, - types: Vec::new(), - type_table: HashMap::new(), - - ast_arena: ast_arena, - ast_counter: 0 } - } - - fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> { - for &ty in &self.types { - if *ty == s { - return ty; - } - } - - let ty = self.ty_arena.alloc(s); - self.types.push(ty); - ty - } - - fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> { - self.type_table.insert(id, ty); - ty - } - - fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> { - let id = self.ast_counter; - self.ast_counter += 1; - self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a }) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -struct NodeId { - id: usize -} - -type Ast<'ast> = &'ast AstStructure<'ast>; - -#[derive(Copy, Clone)] -struct AstStructure<'ast> { - id: NodeId, - kind: AstKind<'ast> -} - -#[derive(Copy, Clone)] -enum AstKind<'ast> { - ExprInt, - ExprVar(usize), - ExprLambda(Ast<'ast>), -} - -fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>, - ast: Ast<'ast>) -> Type<'tcx> -{ - match ast.kind { - ExprInt | ExprVar(_) => { - let ty = tcx.add_type(TypeInt); - tcx.set_type(ast.id, ty) - } - ExprLambda(ast) => { - let arg_ty = tcx.add_type(TypeInt); - let body_ty = compute_types(tcx, ast); - let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty)); - tcx.set_type(ast.id, lambda_ty) - } - } -} - -pub fn main() { - let ty_arena = TypedArena::default(); - let ast_arena = TypedArena::default(); - let mut tcx = TypeContext::new(&ty_arena, &ast_arena); - let ast = tcx.ast(ExprInt); - let ty = compute_types(&mut tcx, ast); - assert_eq!(*ty, TypeInt); -} diff --git a/src/test/run-pass-fulldeps/rename-directory.rs b/src/test/run-pass-fulldeps/rename-directory.rs deleted file mode 100644 index 8fc340cb918..00000000000 --- a/src/test/run-pass-fulldeps/rename-directory.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(unused_imports)] -// This test can't be a unit test in std, -// because it needs TempDir, which is in extra - -// ignore-cross-compile - -use std::env; -use std::ffi::CString; -use std::fs::{self, File}; -use std::path::PathBuf; - -fn rename_directory() { - let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let old_path = tmpdir.join("foo/bar/baz"); - fs::create_dir_all(&old_path).unwrap(); - let test_file = &old_path.join("temp.txt"); - - File::create(test_file).unwrap(); - - let new_path = tmpdir.join("quux/blat"); - fs::create_dir_all(&new_path).unwrap(); - fs::rename(&old_path, &new_path.join("newdir")); - assert!(new_path.join("newdir").is_dir()); - assert!(new_path.join("newdir/temp.txt").exists()); -} - -pub fn main() { rename_directory() } diff --git a/src/test/run-pass-fulldeps/roman-numerals-macro.rs b/src/test/run-pass-fulldeps/roman-numerals-macro.rs deleted file mode 100644 index 5c4ba3158db..00000000000 --- a/src/test/run-pass-fulldeps/roman-numerals-macro.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// aux-build:roman-numerals.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(roman_numerals)] - -pub fn main() { - assert_eq!(rn!(MMXV), 2015); - assert_eq!(rn!(MCMXCIX), 1999); - assert_eq!(rn!(XXV), 25); - assert_eq!(rn!(MDCLXVI), 1666); - assert_eq!(rn!(MMMDCCCLXXXVIII), 3888); - assert_eq!(rn!(MMXIV), 2014); -} diff --git a/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs b/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs deleted file mode 100644 index 42a6153465c..00000000000 --- a/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - -#![feature(rustc_private)] - -#[allow(dead_code)] - -extern crate serialize as rustc_serialize; - -#[derive(RustcDecodable, RustcEncodable,Debug)] -struct A { - a: String, -} - -trait Trait { - fn encode(&self); -} - -impl Trait for T { - fn encode(&self) { - unimplemented!() - } -} - -fn main() {} diff --git a/src/test/run-pass-fulldeps/stdio-from.rs b/src/test/run-pass-fulldeps/stdio-from.rs deleted file mode 100644 index fef9f27fcdf..00000000000 --- a/src/test/run-pass-fulldeps/stdio-from.rs +++ /dev/null @@ -1,69 +0,0 @@ -// run-pass -// ignore-cross-compile - -use std::env; -use std::fs::File; -use std::io; -use std::io::{Read, Write}; -use std::process::{Command, Stdio}; -use std::path::PathBuf; - -fn main() { - if env::args().len() > 1 { - child().unwrap() - } else { - parent().unwrap() - } -} - -fn parent() -> io::Result<()> { - let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let input = td.join("stdio-from-input"); - let output = td.join("stdio-from-output"); - - File::create(&input)?.write_all(b"foo\n")?; - - // Set up this chain: - // $ me file - // ... to duplicate each line 8 times total. - - let mut child1 = Command::new(env::current_exe()?) - .arg("first") - .stdin(File::open(&input)?) // tests File::into() - .stdout(Stdio::piped()) - .spawn()?; - - let mut child3 = Command::new(env::current_exe()?) - .arg("third") - .stdin(Stdio::piped()) - .stdout(File::create(&output)?) // tests File::into() - .spawn()?; - - // Started out of order so we can test both `ChildStdin` and `ChildStdout`. - let mut child2 = Command::new(env::current_exe()?) - .arg("second") - .stdin(child1.stdout.take().unwrap()) // tests ChildStdout::into() - .stdout(child3.stdin.take().unwrap()) // tests ChildStdin::into() - .spawn()?; - - assert!(child1.wait()?.success()); - assert!(child2.wait()?.success()); - assert!(child3.wait()?.success()); - - let mut data = String::new(); - File::open(&output)?.read_to_string(&mut data)?; - for line in data.lines() { - assert_eq!(line, "foo"); - } - assert_eq!(data.lines().count(), 8); - Ok(()) -} - -fn child() -> io::Result<()> { - // double everything - let mut input = vec![]; - io::stdin().read_to_end(&mut input)?; - io::stdout().write_all(&input)?; - io::stdout().write_all(&input)?; - Ok(()) -} diff --git a/src/test/run-pass-fulldeps/switch-stdout.rs b/src/test/run-pass-fulldeps/switch-stdout.rs deleted file mode 100644 index e105637c3da..00000000000 --- a/src/test/run-pass-fulldeps/switch-stdout.rs +++ /dev/null @@ -1,52 +0,0 @@ -// run-pass - -use std::env; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::PathBuf; - -#[cfg(unix)] -fn switch_stdout_to(file: File) { - use std::os::unix::prelude::*; - - extern { - fn dup2(old: i32, new: i32) -> i32; - } - - unsafe { - assert_eq!(dup2(file.as_raw_fd(), 1), 1); - } -} - -#[cfg(windows)] -fn switch_stdout_to(file: File) { - use std::os::windows::prelude::*; - - extern "system" { - fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32; - } - - const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32; - - unsafe { - let rc = SetStdHandle(STD_OUTPUT_HANDLE, - file.into_raw_handle() as *mut _); - assert!(rc != 0); - } -} - -fn main() { - let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let path = path.join("switch-stdout-output"); - let f = File::create(&path).unwrap(); - - println!("foo"); - std::io::stdout().flush().unwrap(); - switch_stdout_to(f); - println!("bar"); - std::io::stdout().flush().unwrap(); - - let mut contents = String::new(); - File::open(&path).unwrap().read_to_string(&mut contents).unwrap(); - assert_eq!(contents, "bar\n"); -} diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs deleted file mode 100644 index 0caccad6229..00000000000 --- a/src/test/run-pass-fulldeps/undef_mask.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// ignore-cross-compile -// ignore-stage1 - -#![feature(rustc_private)] - -extern crate rustc; - -use rustc::mir::interpret::UndefMask; -use rustc::ty::layout::Size; - -fn main() { - let mut mask = UndefMask::new(Size::from_bytes(500), false); - assert!(!mask.get(Size::from_bytes(499))); - mask.set(Size::from_bytes(499), true); - assert!(mask.get(Size::from_bytes(499))); - mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true); - for i in 0..100 { - assert!(!mask.get(Size::from_bytes(i))); - } - for i in 100..256 { - assert!(mask.get(Size::from_bytes(i))); - } - for i in 256..499 { - assert!(!mask.get(Size::from_bytes(i))); - } -} diff --git a/src/test/run-pass/.gitattributes b/src/test/run-pass/.gitattributes deleted file mode 100644 index c6a6f23074d..00000000000 --- a/src/test/run-pass/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -lexer-crlf-line-endings-string-literal-doc-comment.rs -text diff --git a/src/test/run-pass/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi-sysv64-arg-passing.rs deleted file mode 100644 index d40006eb9b6..00000000000 --- a/src/test/run-pass/abi-sysv64-arg-passing.rs +++ /dev/null @@ -1,367 +0,0 @@ -// 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 } - - #[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 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(); - } -} - -#[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(); -} - -#[cfg(not(target_arch = "x86_64"))] -fn main() { - -} diff --git a/src/test/run-pass/abi-sysv64-register-usage.rs b/src/test/run-pass/abi-sysv64-register-usage.rs deleted file mode 100644 index 0c7e2d906b7..00000000000 --- a/src/test/run-pass/abi-sysv64-register-usage.rs +++ /dev/null @@ -1,96 +0,0 @@ -// 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(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)] -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 { - 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/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs deleted file mode 100644 index df819306e4a..00000000000 --- a/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/abort-on-c-abi.rs b/src/test/run-pass/abort-on-c-abi.rs deleted file mode 100644 index cd7dd1b6a45..00000000000 --- a/src/test/run-pass/abort-on-c-abi.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -// 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}; - -extern "C" fn panic_in_ffi() { - panic!("Test"); -} - -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 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(); - assert!(!p.wait().unwrap().success()); -} diff --git a/src/test/run-pass/alias-uninit-value.rs b/src/test/run-pass/alias-uninit-value.rs deleted file mode 100644 index 932c93245e6..00000000000 --- a/src/test/run-pass/alias-uninit-value.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/align-with-extern-c-fn.rs b/src/test/run-pass/align-with-extern-c-fn.rs deleted file mode 100644 index 09abe4fbf7e..00000000000 --- a/src/test/run-pass/align-with-extern-c-fn.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -#![allow(stable_features)] -#![allow(unused_variables)] - -// #45662 - -#![feature(repr_align)] - -#[repr(align(16))] -pub struct A(i64); - -pub extern "C" fn foo(x: A) {} - -fn main() { - foo(A(0)); -} diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs deleted file mode 100644 index c51c56b0899..00000000000 --- a/src/test/run-pass/alignment-gep-tup-like-1.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/alloca-from-derived-tydesc.rs b/src/test/run-pass/alloca-from-derived-tydesc.rs deleted file mode 100644 index c7f7fbad435..00000000000 --- a/src/test/run-pass/alloca-from-derived-tydesc.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs deleted file mode 100644 index 312d5f13b1a..00000000000 --- a/src/test/run-pass/allocator-alloc-one.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass - -#![allow(stable_features)] - -#![feature(allocator_api, nonnull)] - -use std::alloc::{Alloc, Global, Layout, handle_alloc_error}; - -fn main() { - unsafe { - let ptr = Global.alloc_one::().unwrap_or_else(|_| { - handle_alloc_error(Layout::new::()) - }); - *ptr.as_ptr() = 4; - assert_eq!(*ptr.as_ptr(), 4); - Global.dealloc_one(ptr); - } -} diff --git a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs b/src/test/run-pass/allocator/auxiliary/custom-as-global.rs deleted file mode 100644 index a5e96e77501..00000000000 --- a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/allocator/auxiliary/custom.rs b/src/test/run-pass/allocator/auxiliary/custom.rs deleted file mode 100644 index b0ec9ab0929..00000000000 --- a/src/test/run-pass/allocator/auxiliary/custom.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/allocator/auxiliary/helper.rs b/src/test/run-pass/allocator/auxiliary/helper.rs deleted file mode 100644 index 7f6770c226a..00000000000 --- a/src/test/run-pass/allocator/auxiliary/helper.rs +++ /dev/null @@ -1,9 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -use std::fmt; - -pub fn work_with(p: &fmt::Debug) { - drop(p); -} diff --git a/src/test/run-pass/allocator/custom-in-block.rs b/src/test/run-pass/allocator/custom-in-block.rs deleted file mode 100644 index 12813a1fc8b..00000000000 --- a/src/test/run-pass/allocator/custom-in-block.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/allocator/custom-in-submodule.rs b/src/test/run-pass/allocator/custom-in-submodule.rs deleted file mode 100644 index ea341b1ac14..00000000000 --- a/src/test/run-pass/allocator/custom-in-submodule.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/allocator/custom.rs b/src/test/run-pass/allocator/custom.rs deleted file mode 100644 index 71f72ae46c2..00000000000 --- a/src/test/run-pass/allocator/custom.rs +++ /dev/null @@ -1,58 +0,0 @@ -// run-pass - -// aux-build:helper.rs -// no-prefer-dynamic - -#![feature(allocator_api)] - -extern crate helper; - -use std::alloc::{self, Global, Alloc, System, Layout}; -use std::sync::atomic::{AtomicUsize, Ordering}; - -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); - System.alloc(layout) - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - HITS.fetch_add(1, Ordering::SeqCst); - System.dealloc(ptr, 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 ptr = Global.alloc(layout.clone()).unwrap(); - helper::work_with(&ptr); - assert_eq!(HITS.load(Ordering::SeqCst), n + 1); - Global.dealloc(ptr, layout.clone()); - 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 ptr = System.alloc(layout.clone()).unwrap(); - assert_eq!(HITS.load(Ordering::SeqCst), n + 4); - helper::work_with(&ptr); - System.dealloc(ptr, layout); - assert_eq!(HITS.load(Ordering::SeqCst), n + 4); - } -} diff --git a/src/test/run-pass/allocator/xcrate-use.rs b/src/test/run-pass/allocator/xcrate-use.rs deleted file mode 100644 index 039c70e77be..00000000000 --- a/src/test/run-pass/allocator/xcrate-use.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass - -// aux-build:custom.rs -// aux-build:helper.rs -// no-prefer-dynamic - -#![feature(allocator_api)] - -extern crate custom; -extern crate helper; - -use std::alloc::{Global, Alloc, System, Layout}; -use std::sync::atomic::{Ordering, AtomicUsize}; - -#[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 ptr = Global.alloc(layout.clone()).unwrap(); - helper::work_with(&ptr); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); - Global.dealloc(ptr, layout.clone()); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); - - let ptr = System.alloc(layout.clone()).unwrap(); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); - helper::work_with(&ptr); - System.dealloc(ptr, layout); - assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); - } -} diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs deleted file mode 100644 index d8478fb5eaa..00000000000 --- a/src/test/run-pass/allocator/xcrate-use2.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/anon-extern-mod.rs b/src/test/run-pass/anon-extern-mod.rs deleted file mode 100644 index 37a67876c91..00000000000 --- a/src/test/run-pass/anon-extern-mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs deleted file mode 100644 index 74759a4a6bd..00000000000 --- a/src/test/run-pass/argument-passing.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/arr_cycle.rs b/src/test/run-pass/array-slice-vec/arr_cycle.rs deleted file mode 100644 index c262b5a1ff0..00000000000 --- a/src/test/run-pass/array-slice-vec/arr_cycle.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 (b1, b2, b3); - b1 = B::new(); - b2 = B::new(); - b3 = B::new(); - b1.a[0].set(Some(&b2)); - b1.a[1].set(Some(&b3)); - b2.a[0].set(Some(&b2)); - b2.a[1].set(Some(&b3)); - b3.a[0].set(Some(&b1)); - b3.a[1].set(Some(&b2)); -} - -fn main() { - f(); -} diff --git a/src/test/run-pass/array-slice-vec/array_const_index-1.rs b/src/test/run-pass/array-slice-vec/array_const_index-1.rs deleted file mode 100644 index 8ee225f5cdf..00000000000 --- a/src/test/run-pass/array-slice-vec/array_const_index-1.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/run-pass/array-slice-vec/box-of-array-of-drop-1.rs deleted file mode 100644 index d4858932815..00000000000 --- a/src/test/run-pass/array-slice-vec/box-of-array-of-drop-1.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/run-pass/array-slice-vec/box-of-array-of-drop-2.rs deleted file mode 100644 index e8a5b00a55b..00000000000 --- a/src/test/run-pass/array-slice-vec/box-of-array-of-drop-2.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/cast-in-array-size.rs b/src/test/run-pass/array-slice-vec/cast-in-array-size.rs deleted file mode 100644 index b112dcaef3e..00000000000 --- a/src/test/run-pass/array-slice-vec/cast-in-array-size.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/check-static-mut-slices.rs b/src/test/run-pass/array-slice-vec/check-static-mut-slices.rs deleted file mode 100644 index b89c634036e..00000000000 --- a/src/test/run-pass/array-slice-vec/check-static-mut-slices.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/check-static-slice.rs b/src/test/run-pass/array-slice-vec/check-static-slice.rs deleted file mode 100644 index 1c607d13426..00000000000 --- a/src/test/run-pass/array-slice-vec/check-static-slice.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/copy-out-of-array-1.rs b/src/test/run-pass/array-slice-vec/copy-out-of-array-1.rs deleted file mode 100644 index e64985ae3f6..00000000000 --- a/src/test/run-pass/array-slice-vec/copy-out-of-array-1.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/destructure-array-1.rs b/src/test/run-pass/array-slice-vec/destructure-array-1.rs deleted file mode 100644 index 74d893ee5b2..00000000000 --- a/src/test/run-pass/array-slice-vec/destructure-array-1.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/empty-mutable-vec.rs b/src/test/run-pass/array-slice-vec/empty-mutable-vec.rs deleted file mode 100644 index 91ab280b9c7..00000000000 --- a/src/test/run-pass/array-slice-vec/empty-mutable-vec.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -// pretty-expanded FIXME #23616 - -#![allow(unused_mut)] - - -pub fn main() { let mut _v: Vec = Vec::new(); } diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs deleted file mode 100644 index cd2c1722065..00000000000 --- a/src/test/run-pass/array-slice-vec/estr-slice.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/evec-slice.rs b/src/test/run-pass/array-slice-vec/evec-slice.rs deleted file mode 100644 index 4bdf2dbdd6e..00000000000 --- a/src/test/run-pass/array-slice-vec/evec-slice.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/fixed_length_copy.rs b/src/test/run-pass/array-slice-vec/fixed_length_copy.rs deleted file mode 100644 index f73173e8484..00000000000 --- a/src/test/run-pass/array-slice-vec/fixed_length_copy.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/huge-largest-array.rs b/src/test/run-pass/array-slice-vec/huge-largest-array.rs deleted file mode 100644 index 9e78162c813..00000000000 --- a/src/test/run-pass/array-slice-vec/huge-largest-array.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/ivec-pass-by-value.rs b/src/test/run-pass/array-slice-vec/ivec-pass-by-value.rs deleted file mode 100644 index e22aef96330..00000000000 --- a/src/test/run-pass/array-slice-vec/ivec-pass-by-value.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass - -fn f(_a: Vec ) { } -pub fn main() { f(vec![1, 2, 3, 4, 5]); } diff --git a/src/test/run-pass/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs b/src/test/run-pass/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs deleted file mode 100644 index 7afb9d8461f..00000000000 --- a/src/test/run-pass/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/mutable-alias-vec.rs b/src/test/run-pass/array-slice-vec/mutable-alias-vec.rs deleted file mode 100644 index 98dd46824fa..00000000000 --- a/src/test/run-pass/array-slice-vec/mutable-alias-vec.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/nested-vec-1.rs b/src/test/run-pass/array-slice-vec/nested-vec-1.rs deleted file mode 100644 index 02a3ccf46f2..00000000000 --- a/src/test/run-pass/array-slice-vec/nested-vec-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/nested-vec-2.rs b/src/test/run-pass/array-slice-vec/nested-vec-2.rs deleted file mode 100644 index d4a704d767e..00000000000 --- a/src/test/run-pass/array-slice-vec/nested-vec-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/nested-vec-3.rs b/src/test/run-pass/array-slice-vec/nested-vec-3.rs deleted file mode 100644 index 52b892dbcdf..00000000000 --- a/src/test/run-pass/array-slice-vec/nested-vec-3.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/new-style-fixed-length-vec.rs b/src/test/run-pass/array-slice-vec/new-style-fixed-length-vec.rs deleted file mode 100644 index 454f94be876..00000000000 --- a/src/test/run-pass/array-slice-vec/new-style-fixed-length-vec.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -static FOO: [isize; 3] = [1, 2, 3]; - -pub fn main() { - println!("{} {} {}", FOO[0], FOO[1], FOO[2]); -} diff --git a/src/test/run-pass/array-slice-vec/rcvr-borrowed-to-slice.rs b/src/test/run-pass/array-slice-vec/rcvr-borrowed-to-slice.rs deleted file mode 100644 index 17cf7e335b9..00000000000 --- a/src/test/run-pass/array-slice-vec/rcvr-borrowed-to-slice.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/repeated-vector-syntax.rs b/src/test/run-pass/array-slice-vec/repeated-vector-syntax.rs deleted file mode 100644 index 4458eb06dd5..00000000000 --- a/src/test/run-pass/array-slice-vec/repeated-vector-syntax.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/show-boxed-slice.rs b/src/test/run-pass/array-slice-vec/show-boxed-slice.rs deleted file mode 100644 index dfa4c720bb0..00000000000 --- a/src/test/run-pass/array-slice-vec/show-boxed-slice.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#[derive(Debug)] -struct Foo(Box<[u8]>); - -pub fn main() { - println!("{:?}", Foo(Box::new([0, 1, 2]))); -} diff --git a/src/test/run-pass/array-slice-vec/slice-2.rs b/src/test/run-pass/array-slice-vec/slice-2.rs deleted file mode 100644 index 01733f48234..00000000000 --- a/src/test/run-pass/array-slice-vec/slice-2.rs +++ /dev/null @@ -1,62 +0,0 @@ -// run-pass - -// Test slicing expressions on slices and Vecs. - - -fn main() { - let x: &[isize] = &[1, 2, 3, 4, 5]; - let cmp: &[isize] = &[1, 2, 3, 4, 5]; - assert_eq!(&x[..], cmp); - let cmp: &[isize] = &[3, 4, 5]; - assert_eq!(&x[2..], cmp); - let cmp: &[isize] = &[1, 2, 3]; - assert_eq!(&x[..3], cmp); - let cmp: &[isize] = &[2, 3, 4]; - assert_eq!(&x[1..4], cmp); - - let x: Vec = vec![1, 2, 3, 4, 5]; - let cmp: &[isize] = &[1, 2, 3, 4, 5]; - assert_eq!(&x[..], cmp); - let cmp: &[isize] = &[3, 4, 5]; - assert_eq!(&x[2..], cmp); - let cmp: &[isize] = &[1, 2, 3]; - assert_eq!(&x[..3], cmp); - let cmp: &[isize] = &[2, 3, 4]; - assert_eq!(&x[1..4], cmp); - - let x: &mut [isize] = &mut [1, 2, 3, 4, 5]; - { - let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; - assert_eq!(&mut x[..], cmp); - } - { - let cmp: &mut [isize] = &mut [3, 4, 5]; - assert_eq!(&mut x[2..], cmp); - } - { - let cmp: &mut [isize] = &mut [1, 2, 3]; - assert_eq!(&mut x[..3], cmp); - } - { - let cmp: &mut [isize] = &mut [2, 3, 4]; - assert_eq!(&mut x[1..4], cmp); - } - - let mut x: Vec = vec![1, 2, 3, 4, 5]; - { - let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; - assert_eq!(&mut x[..], cmp); - } - { - let cmp: &mut [isize] = &mut [3, 4, 5]; - assert_eq!(&mut x[2..], cmp); - } - { - let cmp: &mut [isize] = &mut [1, 2, 3]; - assert_eq!(&mut x[..3], cmp); - } - { - let cmp: &mut [isize] = &mut [2, 3, 4]; - assert_eq!(&mut x[1..4], cmp); - } -} diff --git a/src/test/run-pass/array-slice-vec/slice-of-zero-size-elements.rs b/src/test/run-pass/array-slice-vec/slice-of-zero-size-elements.rs deleted file mode 100644 index 83b08a3db4c..00000000000 --- a/src/test/run-pass/array-slice-vec/slice-of-zero-size-elements.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/slice-panic-1.rs b/src/test/run-pass/array-slice-vec/slice-panic-1.rs deleted file mode 100644 index 8b27d055e2b..00000000000 --- a/src/test/run-pass/array-slice-vec/slice-panic-1.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/slice-panic-2.rs b/src/test/run-pass/array-slice-vec/slice-panic-2.rs deleted file mode 100644 index 2ee564cadb3..00000000000 --- a/src/test/run-pass/array-slice-vec/slice-panic-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/slice.rs b/src/test/run-pass/array-slice-vec/slice.rs deleted file mode 100644 index 14e1ddf52eb..00000000000 --- a/src/test/run-pass/array-slice-vec/slice.rs +++ /dev/null @@ -1,81 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/slice_binary_search.rs b/src/test/run-pass/array-slice-vec/slice_binary_search.rs deleted file mode 100644 index 12236960179..00000000000 --- a/src/test/run-pass/array-slice-vec/slice_binary_search.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/variance-vec-covariant.rs b/src/test/run-pass/array-slice-vec/variance-vec-covariant.rs deleted file mode 100644 index d7e64132f89..00000000000 --- a/src/test/run-pass/array-slice-vec/variance-vec-covariant.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-concat.rs b/src/test/run-pass/array-slice-vec/vec-concat.rs deleted file mode 100644 index 1f493679b79..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-concat.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -use std::vec; - -pub fn main() { - let a: Vec = vec![1, 2, 3, 4, 5]; - let b: Vec = vec![6, 7, 8, 9, 0]; - let mut v: Vec = a; - v.extend_from_slice(&b); - println!("{}", v[9]); - assert_eq!(v[0], 1); - assert_eq!(v[7], 8); - assert_eq!(v[9], 0); -} diff --git a/src/test/run-pass/array-slice-vec/vec-dst.rs b/src/test/run-pass/array-slice-vec/vec-dst.rs deleted file mode 100644 index e741201652b..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-dst.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-fixed-length.rs b/src/test/run-pass/array-slice-vec/vec-fixed-length.rs deleted file mode 100644 index 5db02ee066b..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-fixed-length.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-growth.rs b/src/test/run-pass/array-slice-vec/vec-growth.rs deleted file mode 100644 index b09f08bb85a..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-growth.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - - - -pub fn main() { - let mut v = vec![1]; - v.push(2); - v.push(3); - v.push(4); - v.push(5); - assert_eq!(v[0], 1); - assert_eq!(v[1], 2); - assert_eq!(v[2], 3); - assert_eq!(v[3], 4); - assert_eq!(v[4], 5); -} diff --git a/src/test/run-pass/array-slice-vec/vec-late-init.rs b/src/test/run-pass/array-slice-vec/vec-late-init.rs deleted file mode 100644 index 5dee3608256..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-late-init.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs deleted file mode 100644 index 443895f7c48..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-macro-repeat.rs b/src/test/run-pass/array-slice-vec/vec-macro-repeat.rs deleted file mode 100644 index 7be8dadbe17..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-macro-repeat.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - - - -pub fn main() { - assert_eq!(vec![1; 3], vec![1, 1, 1]); - assert_eq!(vec![1; 2], vec![1, 1]); - assert_eq!(vec![1; 1], vec![1]); - assert_eq!(vec![1; 0], vec![]); - - // from_elem syntax (see RFC 832) - let el = Box::new(1); - let n = 3; - assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); -} diff --git a/src/test/run-pass/array-slice-vec/vec-macro-rvalue-scope.rs b/src/test/run-pass/array-slice-vec/vec-macro-rvalue-scope.rs deleted file mode 100644 index bde01037181..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-macro-rvalue-scope.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-macro-with-brackets.rs b/src/test/run-pass/array-slice-vec/vec-macro-with-brackets.rs deleted file mode 100644 index 6c95bd50007..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-macro-with-brackets.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-macro-with-trailing-comma.rs b/src/test/run-pass/array-slice-vec/vec-macro-with-trailing-comma.rs deleted file mode 100644 index f7a51f9c456..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-macro-with-trailing-comma.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - - - -pub fn main() { - assert_eq!(vec![1], vec![1,]); - assert_eq!(vec![1, 2, 3], vec![1, 2, 3,]); -} diff --git a/src/test/run-pass/array-slice-vec/vec-matching-autoslice.rs b/src/test/run-pass/array-slice-vec/vec-matching-autoslice.rs deleted file mode 100644 index 8179edf420c..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-matching-autoslice.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/array-slice-vec/vec-matching-fixed.rs b/src/test/run-pass/array-slice-vec/vec-matching-fixed.rs deleted file mode 100644 index 5253bc1b214..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-matching-fixed.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass - -#![feature(slice_patterns)] - -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/src/test/run-pass/array-slice-vec/vec-matching-fold.rs b/src/test/run-pass/array-slice-vec/vec-matching-fold.rs deleted file mode 100644 index 2b19c49c427..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-matching-fold.rs +++ /dev/null @@ -1,48 +0,0 @@ -// run-pass - -#![feature(slice_patterns)] - -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/src/test/run-pass/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/run-pass/array-slice-vec/vec-matching-legal-tail-element-borrow.rs deleted file mode 100644 index bce03b3375e..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-matching-legal-tail-element-borrow.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -#![allow(unused_variables)] - -#![feature(slice_patterns)] - -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/src/test/run-pass/array-slice-vec/vec-matching.rs b/src/test/run-pass/array-slice-vec/vec-matching.rs deleted file mode 100644 index a37c25160fa..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-matching.rs +++ /dev/null @@ -1,159 +0,0 @@ -// run-pass - -#![feature(slice_patterns)] - -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); -} - -fn f() { - let x = &[1, 2, 3, 4, 5]; - let [a, [b, [c, ..].., d].., e] = *x; - assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); - - let x: &[isize] = x; - let (a, b, c, d, e) = match *x { - [a, [b, [c, ..].., d].., e] => (a, b, c, d, e), - _ => unimplemented!() - }; - - assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); -} - -pub fn main() { - a(); - b(); - b_slice(); - c(); - d(); - e(); - f(); -} diff --git a/src/test/run-pass/array-slice-vec/vec-push.rs b/src/test/run-pass/array-slice-vec/vec-push.rs deleted file mode 100644 index 466ab3fab1c..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-push.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn main() { let mut v = vec![1, 2, 3]; v.push(1); } diff --git a/src/test/run-pass/array-slice-vec/vec-repeat-with-cast.rs b/src/test/run-pass/array-slice-vec/vec-repeat-with-cast.rs deleted file mode 100644 index 3e0e18873ab..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-repeat-with-cast.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -// pretty-expanded FIXME #23616 - -pub fn main() { let _a = [0; 1 as usize]; } diff --git a/src/test/run-pass/array-slice-vec/vec-slice-drop.rs b/src/test/run-pass/array-slice-vec/vec-slice-drop.rs deleted file mode 100644 index 3a9ea86af34..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-slice-drop.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] - -use std::cell::Cell; - -// Make sure that destructors get run on slice literals -struct foo<'a> { - x: &'a Cell, -} - -impl<'a> Drop for foo<'a> { - fn drop(&mut self) { - self.x.set(self.x.get() + 1); - } -} - -fn foo(x: &Cell) -> foo { - foo { - x: x - } -} - -pub fn main() { - let x = &Cell::new(0); - { - let l = &[foo(x)]; - assert_eq!(l[0].x.get(), 0); - } - assert_eq!(x.get(), 1); -} diff --git a/src/test/run-pass/array-slice-vec/vec-slice.rs b/src/test/run-pass/array-slice-vec/vec-slice.rs deleted file mode 100644 index 1f090ddd9c9..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-slice.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - - -pub fn main() { - let v = vec![1,2,3,4,5]; - let v2 = &v[1..3]; - assert_eq!(v2[0], 2); - assert_eq!(v2[1], 3); -} diff --git a/src/test/run-pass/array-slice-vec/vec-tail-matching.rs b/src/test/run-pass/array-slice-vec/vec-tail-matching.rs deleted file mode 100644 index 84d246dff82..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-tail-matching.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass - -#![feature(slice_patterns)] - -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/src/test/run-pass/array-slice-vec/vec-to_str.rs b/src/test/run-pass/array-slice-vec/vec-to_str.rs deleted file mode 100644 index a11cfc8e9b5..00000000000 --- a/src/test/run-pass/array-slice-vec/vec-to_str.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - - -pub fn main() { - assert_eq!(format!("{:?}", vec![0, 1]), "[0, 1]".to_string()); - - let foo = vec![3, 4]; - let bar: &[isize] = &[4, 5]; - - assert_eq!(format!("{:?}", foo), "[3, 4]"); - assert_eq!(format!("{:?}", bar), "[4, 5]"); -} diff --git a/src/test/run-pass/array-slice-vec/vec.rs b/src/test/run-pass/array-slice-vec/vec.rs deleted file mode 100644 index e76c1ab440e..00000000000 --- a/src/test/run-pass/array-slice-vec/vec.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - - - -pub fn main() { - let v: Vec = vec![10, 20]; - assert_eq!(v[0], 10); - assert_eq!(v[1], 20); - let mut x: usize = 0; - assert_eq!(v[x], 10); - assert_eq!(v[x + 1], 20); - x = x + 1; - assert_eq!(v[x], 20); - assert_eq!(v[x - 1], 10); -} diff --git a/src/test/run-pass/array-slice-vec/vec_cycle.rs b/src/test/run-pass/array-slice-vec/vec_cycle.rs deleted file mode 100644 index 82bce437282..00000000000 --- a/src/test/run-pass/array-slice-vec/vec_cycle.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass - -use std::cell::Cell; - -#[derive(Debug)] -struct C<'a> { - v: Vec>>>, -} - -impl<'a> C<'a> { - fn new() -> C<'a> { - C { v: Vec::new() } - } -} - -fn f() { - let (mut c1, mut c2, mut c3); - c1 = C::new(); - c2 = C::new(); - c3 = C::new(); - - c1.v.push(Cell::new(None)); - c1.v.push(Cell::new(None)); - c2.v.push(Cell::new(None)); - c2.v.push(Cell::new(None)); - c3.v.push(Cell::new(None)); - c3.v.push(Cell::new(None)); - - c1.v[0].set(Some(&c2)); - c1.v[1].set(Some(&c3)); - c2.v[0].set(Some(&c2)); - c2.v[1].set(Some(&c3)); - c3.v[0].set(Some(&c1)); - c3.v[1].set(Some(&c2)); -} - -fn main() { - f(); -} diff --git a/src/test/run-pass/array-slice-vec/vec_cycle_wrapped.rs b/src/test/run-pass/array-slice-vec/vec_cycle_wrapped.rs deleted file mode 100644 index 1a3606d5e8d..00000000000 --- a/src/test/run-pass/array-slice-vec/vec_cycle_wrapped.rs +++ /dev/null @@ -1,50 +0,0 @@ -// run-pass - -use std::cell::Cell; - -#[derive(Debug)] -struct Refs<'a> { - v: Vec>>>, -} - -#[derive(Debug)] -struct C<'a> { - refs: Refs<'a>, -} - -impl<'a> Refs<'a> { - fn new() -> Refs<'a> { - Refs { v: Vec::new() } - } -} - -impl<'a> C<'a> { - fn new() -> C<'a> { - C { refs: Refs::new() } - } -} - -fn f() { - let (mut c1, mut c2, mut c3); - c1 = C::new(); - c2 = C::new(); - c3 = C::new(); - - c1.refs.v.push(Cell::new(None)); - c1.refs.v.push(Cell::new(None)); - c2.refs.v.push(Cell::new(None)); - c2.refs.v.push(Cell::new(None)); - c3.refs.v.push(Cell::new(None)); - c3.refs.v.push(Cell::new(None)); - - c1.refs.v[0].set(Some(&c2)); - c1.refs.v[1].set(Some(&c3)); - c2.refs.v[0].set(Some(&c2)); - c2.refs.v[1].set(Some(&c3)); - c3.refs.v[0].set(Some(&c1)); - c3.refs.v[1].set(Some(&c2)); -} - -fn main() { - f(); -} diff --git a/src/test/run-pass/array-slice-vec/vector-no-ann-2.rs b/src/test/run-pass/array-slice-vec/vector-no-ann-2.rs deleted file mode 100644 index dd8f402f3f6..00000000000 --- a/src/test/run-pass/array-slice-vec/vector-no-ann-2.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -// pretty-expanded FIXME #23616 - -#![feature(box_syntax)] - -pub fn main() { let _quux: Box> = box Vec::new(); } diff --git a/src/test/run-pass/artificial-block.rs b/src/test/run-pass/artificial-block.rs deleted file mode 100644 index 2e383e1a7c6..00000000000 --- a/src/test/run-pass/artificial-block.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -fn f() -> isize { { return 3; } } - -pub fn main() { assert_eq!(f(), 3); } diff --git a/src/test/run-pass/as-precedence.rs b/src/test/run-pass/as-precedence.rs deleted file mode 100644 index a9f6fceb08f..00000000000 --- a/src/test/run-pass/as-precedence.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -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/src/test/run-pass/asm-concat-src.rs b/src/test/run-pass/asm-concat-src.rs deleted file mode 100644 index c4160bfeca1..00000000000 --- a/src/test/run-pass/asm-concat-src.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 -// ignore-emscripten no asm - -#![feature(asm)] - -pub fn main() { - unsafe { asm!(concat!("", "")) }; -} diff --git a/src/test/run-pass/asm-in-moved.rs b/src/test/run-pass/asm-in-moved.rs deleted file mode 100644 index 6525d2f53b0..00000000000 --- a/src/test/run-pass/asm-in-moved.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass - -#![feature(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 { - 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/src/test/run-pass/asm-in-out-operand.rs b/src/test/run-pass/asm-in-out-operand.rs deleted file mode 100644 index 13d0363a6a0..00000000000 --- a/src/test/run-pass/asm-in-out-operand.rs +++ /dev/null @@ -1,56 +0,0 @@ -// run-pass - -#![feature(asm)] - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -unsafe fn next_power_of_2(n: u32) -> u32 { - let mut tmp = n; - asm!("dec $0" : "+rm"(tmp) :: "cc"); - let mut shift = 1_u32; - while shift <= 16 { - asm!( - "shr %cl, $2 - or $2, $0 - shl $$1, $1" - : "+&rm"(tmp), "+{ecx}"(shift) : "r"(tmp) : "cc" - ); - } - 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. - 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. - 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/src/test/run-pass/asm-indirect-memory.rs b/src/test/run-pass/asm-indirect-memory.rs deleted file mode 100644 index 2e8011af502..00000000000 --- a/src/test/run-pass/asm-indirect-memory.rs +++ /dev/null @@ -1,43 +0,0 @@ -// run-pass - -#![feature(asm)] - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -fn read(ptr: &u32) -> u32 { - let out: u32; - unsafe { - 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 { - 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 { - 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/src/test/run-pass/asm-out-assign.rs b/src/test/run-pass/asm-out-assign.rs deleted file mode 100644 index ed63d1b4d49..00000000000 --- a/src/test/run-pass/asm-out-assign.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass - -#![feature(asm)] - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub fn main() { - let x: isize; - unsafe { - // Treat the output as initialization. - 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. - 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/src/test/run-pass/assert-eq-trailing-comma.rs b/src/test/run-pass/assert-eq-trailing-comma.rs deleted file mode 100644 index 7071f80d7f7..00000000000 --- a/src/test/run-pass/assert-eq-trailing-comma.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -fn main() { - assert_eq!(1, 1,); -} diff --git a/src/test/run-pass/assert-escape.rs b/src/test/run-pass/assert-escape.rs deleted file mode 100644 index 00e51d42cab..00000000000 --- a/src/test/run-pass/assert-escape.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -fn main() { - assert!(r#"☃\backslash"#.contains("\\")); -} diff --git a/src/test/run-pass/assert-ne-trailing-comma.rs b/src/test/run-pass/assert-ne-trailing-comma.rs deleted file mode 100644 index 03308db9a1f..00000000000 --- a/src/test/run-pass/assert-ne-trailing-comma.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -fn main() { - assert_ne!(1, 2,); -} diff --git a/src/test/run-pass/assign-assign.rs b/src/test/run-pass/assign-assign.rs deleted file mode 100644 index bcf506b398b..00000000000 --- a/src/test/run-pass/assign-assign.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/assoc-oddities-3.rs b/src/test/run-pass/assoc-oddities-3.rs deleted file mode 100644 index cd025dc8bee..00000000000 --- a/src/test/run-pass/assoc-oddities-3.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-const-eval.rs b/src/test/run-pass/associated-consts/associated-const-const-eval.rs deleted file mode 100644 index 5a34bb97ca5..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-const-eval.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-cross-crate-const-eval.rs b/src/test/run-pass/associated-consts/associated-const-cross-crate-const-eval.rs deleted file mode 100644 index 611639b84be..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-cross-crate-const-eval.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-cross-crate-defaults.rs b/src/test/run-pass/associated-consts/associated-const-cross-crate-defaults.rs deleted file mode 100644 index 92d9cffecdd..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-cross-crate-defaults.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-cross-crate.rs b/src/test/run-pass/associated-consts/associated-const-cross-crate.rs deleted file mode 100644 index ecdc112e02d..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-cross-crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-in-global-const.rs b/src/test/run-pass/associated-consts/associated-const-in-global-const.rs deleted file mode 100644 index 18d7a121558..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-in-global-const.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-inherent-impl.rs b/src/test/run-pass/associated-consts/associated-const-inherent-impl.rs deleted file mode 100644 index c6d956dffe1..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-inherent-impl.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -struct Foo; - -impl Foo { - const ID: i32 = 1; -} - -fn main() { - assert_eq!(1, Foo::ID); -} diff --git a/src/test/run-pass/associated-consts/associated-const-marks-live-code.rs b/src/test/run-pass/associated-consts/associated-const-marks-live-code.rs deleted file mode 100644 index 68eb4e25d33..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-marks-live-code.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-match-patterns.rs b/src/test/run-pass/associated-consts/associated-const-match-patterns.rs deleted file mode 100644 index 62c1cb983d1..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-match-patterns.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-outer-ty-refs.rs b/src/test/run-pass/associated-consts/associated-const-outer-ty-refs.rs deleted file mode 100644 index f32ca0cccfc..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-outer-ty-refs.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -trait Lattice { - const BOTTOM: Self; -} - -impl Lattice for Option { - const BOTTOM: Option = None; -} - -fn main(){} diff --git a/src/test/run-pass/associated-consts/associated-const-overwrite-default.rs b/src/test/run-pass/associated-consts/associated-const-overwrite-default.rs deleted file mode 100644 index 445135aef2b..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-overwrite-default.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-public-impl.rs b/src/test/run-pass/associated-consts/associated-const-public-impl.rs deleted file mode 100644 index 787bee0ff02..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-public-impl.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs b/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs deleted file mode 100644 index 5276869a702..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-resolution-order.rs b/src/test/run-pass/associated-consts/associated-const-resolution-order.rs deleted file mode 100644 index d2ccd30a6e2..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-resolution-order.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-self-type.rs b/src/test/run-pass/associated-consts/associated-const-self-type.rs deleted file mode 100644 index 36e1e4ecce7..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-self-type.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -trait MyInt { - const ONE: Self; -} - -impl MyInt for i32 { - const ONE: i32 = 1; -} - -fn main() { - assert_eq!(1, ::ONE); -} diff --git a/src/test/run-pass/associated-consts/associated-const-type-parameters.rs b/src/test/run-pass/associated-consts/associated-const-type-parameters.rs deleted file mode 100644 index 47c3313ec28..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-type-parameters.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const-ufcs-infer-trait.rs b/src/test/run-pass/associated-consts/associated-const-ufcs-infer-trait.rs deleted file mode 100644 index ca44c9f45fc..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-ufcs-infer-trait.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -trait Foo { - const ID: i32; -} - -impl Foo for i32 { - const ID: i32 = 1; -} - -fn main() { - assert_eq!(1, ::ID); -} diff --git a/src/test/run-pass/associated-consts/associated-const-use-default.rs b/src/test/run-pass/associated-consts/associated-const-use-default.rs deleted file mode 100644 index adf36b1fff2..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-use-default.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -trait Foo { - const ID: i32 = 1; -} - -impl Foo for i32 {} - -fn main() { - assert_eq!(1, ::ID); -} diff --git a/src/test/run-pass/associated-consts/associated-const-use-impl-of-same-trait.rs b/src/test/run-pass/associated-consts/associated-const-use-impl-of-same-trait.rs deleted file mode 100644 index 8f01bae4fcf..00000000000 --- a/src/test/run-pass/associated-consts/associated-const-use-impl-of-same-trait.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/associated-consts/associated-const.rs b/src/test/run-pass/associated-consts/associated-const.rs deleted file mode 100644 index e4b1c29f371..00000000000 --- a/src/test/run-pass/associated-consts/associated-const.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -trait Foo { - const ID: i32; -} - -impl Foo for i32 { - const ID: i32 = 1; -} - -fn main() { - assert_eq!(1, ::ID); -} diff --git a/src/test/run-pass/associated-consts/auxiliary/associated-const-cc-lib.rs b/src/test/run-pass/associated-consts/auxiliary/associated-const-cc-lib.rs deleted file mode 100644 index 4fcefe32cbf..00000000000 --- a/src/test/run-pass/associated-consts/auxiliary/associated-const-cc-lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![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/src/test/run-pass/associated-consts/auxiliary/empty-struct.rs b/src/test/run-pass/associated-consts/auxiliary/empty-struct.rs deleted file mode 100644 index 93275e7143e..00000000000 --- a/src/test/run-pass/associated-consts/auxiliary/empty-struct.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct XEmpty1 {} -pub struct XEmpty2; -pub struct XEmpty7(); - -pub enum XE { - XEmpty3 {}, - XEmpty4, - XEmpty6(), -} diff --git a/src/test/run-pass/associated-item-long-paths.rs b/src/test/run-pass/associated-item-long-paths.rs deleted file mode 100644 index aad8c487c5a..00000000000 --- a/src/test/run-pass/associated-item-long-paths.rs +++ /dev/null @@ -1,47 +0,0 @@ -// run-pass - -use std::mem::size_of; - -// The main point of this test is to ensure that we can parse and resolve -// associated items on associated types. - -trait Foo { - type U; -} - -trait Bar { - // Note 1: Chains of associated items in a path won't type-check. - // Note 2: Associated consts can't depend on type parameters or `Self`, - // which are the only types that an associated type can be referenced on for - // now, so we can only test methods. - fn method() -> u32; - fn generic_method() -> usize; -} - -struct MyFoo; -struct MyBar; - -impl Foo for MyFoo { - type U = MyBar; -} - -impl Bar for MyBar { - fn method() -> u32 { - 2u32 - } - fn generic_method() -> usize { - size_of::() - } -} - -fn foo() - where T: Foo, - T::U: Bar, -{ - assert_eq!(2u32, ::U::method()); - assert_eq!(8usize, ::U::generic_method::()); -} - -fn main() { - foo::(); -} diff --git a/src/test/run-pass/associated-types/associated-types-basic.rs b/src/test/run-pass/associated-types/associated-types-basic.rs deleted file mode 100644 index b7f6721ec4f..00000000000 --- a/src/test/run-pass/associated-types/associated-types-basic.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -trait Foo { - type T; -} - -impl Foo for i32 { - type T = isize; -} - -fn main() { - let x: ::T = 22; - let y: isize = 44; - assert_eq!(x * 2, y); -} diff --git a/src/test/run-pass/associated-types/associated-types-binding-in-trait.rs b/src/test/run-pass/associated-types/associated-types-binding-in-trait.rs deleted file mode 100644 index 2e42b3a2a44..00000000000 --- a/src/test/run-pass/associated-types/associated-types-binding-in-trait.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass -// Test a case where the associated type binding (to `bool`, in this -// case) is derived from the trait definition. Issue #21636. - - -use std::vec; - -pub trait BitIter { - type Iter: Iterator; - fn bit_iter(self) -> ::Iter; -} - -impl BitIter for Vec { - type Iter = vec::IntoIter; - fn bit_iter(self) -> ::Iter { - self.into_iter() - } -} - -fn count(arg: T) -> usize - where T: BitIter -{ - let mut sum = 0; - for i in arg.bit_iter() { - if i { - sum += 1; - } - } - sum -} - -fn main() { - let v = vec![true, false, true]; - let c = count(v); - assert_eq!(c, 2); -} diff --git a/src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs b/src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs deleted file mode 100644 index c54bc3cd623..00000000000 --- a/src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -// Test equality constraints on associated types in a where clause. - -// pretty-expanded FIXME #23616 - -pub trait Foo { - type A; - fn boo(&self) -> ::A; -} - -#[derive(PartialEq)] -pub struct Bar; - -impl Foo for isize { - type A = usize; - fn boo(&self) -> usize { 42 } -} - -impl Foo for char { - type A = Bar; - fn boo(&self) -> Bar { Bar } -} - -fn foo_bar>(x: I) -> Bar { - x.boo() -} - -fn foo_uint>(x: I) -> usize { - x.boo() -} - -pub fn main() { - let a = 42; - foo_uint(a); - - let a = 'a'; - foo_bar(a); -} diff --git a/src/test/run-pass/associated-types/associated-types-bound.rs b/src/test/run-pass/associated-types/associated-types-bound.rs deleted file mode 100644 index 0e9a229a5e5..00000000000 --- a/src/test/run-pass/associated-types/associated-types-bound.rs +++ /dev/null @@ -1,43 +0,0 @@ -// run-pass -// Test equality constrai32s on associated types in a where clause. - - -pub trait ToI32 { - fn to_i32(&self) -> i32; -} - -impl ToI32 for i32 { - fn to_i32(&self) -> i32 { *self } -} - -impl ToI32 for u32 { - fn to_i32(&self) -> i32 { *self as i32 } -} - -pub trait GetToI32 -{ - type R : ToI32; - - fn get(&self) -> ::R; -} - -impl GetToI32 for i32 { - type R = i32; - fn get(&self) -> i32 { *self } -} - -impl GetToI32 for u32 { - type R = u32; - fn get(&self) -> u32 { *self } -} - -fn foo(g: G) -> i32 - where G : GetToI32 -{ - ToI32::to_i32(&g.get()) -} - -pub fn main() { - assert_eq!(foo(22i32), 22); - assert_eq!(foo(22u32), 22); -} diff --git a/src/test/run-pass/associated-types/associated-types-cc.rs b/src/test/run-pass/associated-types/associated-types-cc.rs deleted file mode 100644 index 13f1d27203a..00000000000 --- a/src/test/run-pass/associated-types/associated-types-cc.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// aux-build:associated-types-cc-lib.rs - -// Test that we are able to reference cross-crate traits that employ -// associated types. - -extern crate associated_types_cc_lib as bar; - -use bar::Bar; - -fn foo(b: B) -> ::T { - Bar::get(None::) -} - -fn main() { - println!("{}", foo(3)); -} diff --git a/src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs deleted file mode 100644 index 70ee60517ae..00000000000 --- a/src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs +++ /dev/null @@ -1,66 +0,0 @@ -// run-pass -// Test that we evaluate projection predicates to winnow out -// candidates during trait selection and method resolution (#20296). -// If we don't properly winnow out candidates based on the output type -// `Target=[A]`, then the impl marked with `(*)` is seen to conflict -// with all the others. - -// pretty-expanded FIXME #23616 - -use std::marker::PhantomData; -use std::ops::Deref; - -pub trait MyEq { - fn eq(&self, u: &U) -> bool; -} - -impl MyEq<[B]> for [A] - where A : MyEq -{ - fn eq(&self, other: &[B]) -> bool { - self.len() == other.len() && - self.iter().zip(other).all(|(a, b)| MyEq::eq(a, b)) - } -} - -// (*) This impl conflicts with everything unless the `Target=[A]` -// constraint is considered. -impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs - where A: MyEq, Lhs: Deref -{ - fn eq(&self, other: &[B; 0]) -> bool { - MyEq::eq(&**self, other) - } -} - -struct DerefWithHelper { - pub helper: H, - pub marker: PhantomData, -} - -trait Helper { - fn helper_borrow(&self) -> &T; -} - -impl Helper for Option { - fn helper_borrow(&self) -> &T { - self.as_ref().unwrap() - } -} - -impl> Deref for DerefWithHelper { - type Target = T; - - fn deref(&self) -> &T { - self.helper.helper_borrow() - } -} - -pub fn check(x: T, y: T) -> bool { - let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), - marker: PhantomData }; - d.eq(&y) -} - -pub fn main() { -} diff --git a/src/test/run-pass/associated-types/associated-types-constant-type.rs b/src/test/run-pass/associated-types/associated-types-constant-type.rs deleted file mode 100644 index 1e4c113a5fb..00000000000 --- a/src/test/run-pass/associated-types/associated-types-constant-type.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass - -trait SignedUnsigned { - type Opposite; - fn convert(self) -> Self::Opposite; -} - -impl SignedUnsigned for isize { - type Opposite = usize; - - fn convert(self) -> usize { - self as usize - } -} - -impl SignedUnsigned for usize { - type Opposite = isize; - - fn convert(self) -> isize { - self as isize - } -} - -fn get(x: isize) -> ::Opposite { - x.convert() -} - -fn main() { - let x = get(22); - assert_eq!(22, x); -} diff --git a/src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs b/src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs deleted file mode 100644 index 96ba2ee3b62..00000000000 --- a/src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs deleted file mode 100644 index 12ca100435a..00000000000 --- a/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Check that we do not report ambiguities when equivalent predicates -// (modulo bound lifetime names) appears in the environment -// twice. Issue #21965. - -// pretty-expanded FIXME #23616 - -fn foo(t: T) -> i32 - where T : for<'a> Fn(&'a u8) -> i32, - T : for<'b> Fn(&'b u8) -> i32, -{ - t(&3) -} - -fn main() { -} diff --git a/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs b/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs deleted file mode 100644 index 9ffccd3d8ff..00000000000 --- a/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Check that we do not report ambiguities when the same predicate -// appears in the environment twice. Issue #21965. - -// pretty-expanded FIXME #23616 - -trait Foo { - type B; - - fn get() -> Self::B; -} - -fn foo() -> () - where T : Foo, T : Foo -{ - ::get() -} - -fn main() { -} diff --git a/src/test/run-pass/associated-types/associated-types-enum-field-named.rs b/src/test/run-pass/associated-types/associated-types-enum-field-named.rs deleted file mode 100644 index 896d67213e9..00000000000 --- a/src/test/run-pass/associated-types/associated-types-enum-field-named.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// Test associated types appearing in struct-like enum variants. - - -use self::VarValue::*; - -pub trait UnifyKey { - type Value; - fn to_index(&self) -> usize; -} - -pub enum VarValue { - Redirect { to: K }, - Root { value: K::Value, rank: usize }, -} - -fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { - match table[key.to_index()] { - VarValue::Redirect { to: ref k } => get(table, k), - VarValue::Root { value: ref v, rank: _ } => v, - } -} - -impl UnifyKey for usize { - type Value = Option; - fn to_index(&self) -> usize { *self } -} - -fn main() { - let table = vec![/* 0 */ Redirect { to: 1 }, - /* 1 */ Redirect { to: 3 }, - /* 2 */ Root { value: Some('x'), rank: 0 }, - /* 3 */ Redirect { to: 2 }]; - assert_eq!(get(&table, &0), &Some('x')); -} diff --git a/src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs b/src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs deleted file mode 100644 index 77ced3c0781..00000000000 --- a/src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// Test associated types appearing in tuple-like enum variants. - - -use self::VarValue::*; - -pub trait UnifyKey { - type Value; - fn to_index(&self) -> usize; -} - -pub enum VarValue { - Redirect(K), - Root(K::Value, usize), -} - -fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { - match table[key.to_index()] { - VarValue::Redirect(ref k) => get(table, k), - VarValue::Root(ref v, _) => v, - } -} - -impl UnifyKey for usize { - type Value = Option; - fn to_index(&self) -> usize { *self } -} - -fn main() { - let table = vec![/* 0 */ Redirect(1), - /* 1 */ Redirect(3), - /* 2 */ Root(Some('x'), 0), - /* 3 */ Redirect(2)]; - assert_eq!(get(&table, &0), &Some('x')); -} diff --git a/src/test/run-pass/associated-types/associated-types-eq-obj.rs b/src/test/run-pass/associated-types/associated-types-eq-obj.rs deleted file mode 100644 index c202c376c5f..00000000000 --- a/src/test/run-pass/associated-types/associated-types-eq-obj.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -// Test equality constraints on associated types inside of an object type - -// pretty-expanded FIXME #23616 - -pub trait Foo { - type A; - fn boo(&self) -> ::A; -} - -pub struct Bar; - -impl Foo for char { - type A = Bar; - fn boo(&self) -> Bar { Bar } -} - -fn baz(x: &dyn Foo) -> Bar { - x.boo() -} - -pub fn main() { - let a = 'a'; - baz(&a); -} diff --git a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs b/src/test/run-pass/associated-types/associated-types-from-supertrait.rs deleted file mode 100644 index 8f40b94c099..00000000000 --- a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -trait Foo: Iterator {} -trait Bar: Foo {} - -fn main() { - let _: &dyn Bar; -} diff --git a/src/test/run-pass/associated-types/associated-types-impl-redirect.rs b/src/test/run-pass/associated-types/associated-types-impl-redirect.rs deleted file mode 100644 index 8fa20cdf4b7..00000000000 --- a/src/test/run-pass/associated-types/associated-types-impl-redirect.rs +++ /dev/null @@ -1,51 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_mut)] -#![allow(unused_imports)] -// Test how resolving a projection interacts with inference. In this -// case, we were eagerly unifying the type variable for the iterator -// type with `I` from the where clause, ignoring the in-scope `impl` -// for `ByRef`. The right answer was to consider the result ambiguous -// until more type information was available. - -#![feature(lang_items)] -#![no_implicit_prelude] - -use std::marker::Sized; -use std::option::Option::{None, Some, self}; - -trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} - -trait IteratorExt: Iterator + Sized { - fn by_ref(&mut self) -> ByRef { - ByRef(self) - } -} - -impl IteratorExt for I where I: Iterator {} - -struct ByRef<'a, I: 'a + Iterator>(&'a mut I); - -impl<'a, I: Iterator> Iterator for ByRef<'a, I> { - type Item = I::Item; - - fn next(&mut self) -> Option< ::Item > { - self.0.next() - } -} - -fn is_iterator_of>(_: &I) {} - -fn test>(mut it: I) { - is_iterator_of::(&it.by_ref()); -} - -fn test2, I2: Iterator>(mut it: I2) { - is_iterator_of::(&it) -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs b/src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs deleted file mode 100644 index 88bb5fe0afe..00000000000 --- a/src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// Test the case where we resolve `C::Result` and the trait bound -// itself includes a `Self::Item` shorthand. -// -// Regression test for issue #33425. - -trait ParallelIterator { - type Item; - fn drive_unindexed(self, consumer: C) -> C::Result - where C: Consumer; -} - -pub trait Consumer { - type Result; -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-in-default-method.rs b/src/test/run-pass/associated-types/associated-types-in-default-method.rs deleted file mode 100644 index 80ffbf585fb..00000000000 --- a/src/test/run-pass/associated-types/associated-types-in-default-method.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass - -trait Get { - type Value; - fn get(&self) -> &::Value; - fn grab(&self) -> &::Value { - self.get() - } -} - -struct Struct { - x: isize, -} - -impl Get for Struct { - type Value = isize; - fn get(&self) -> &isize { - &self.x - } -} - -fn main() { - let s = Struct { - x: 100, - }; - assert_eq!(*s.grab(), 100); -} diff --git a/src/test/run-pass/associated-types/associated-types-in-fn.rs b/src/test/run-pass/associated-types/associated-types-in-fn.rs deleted file mode 100644 index 9c588a528fe..00000000000 --- a/src/test/run-pass/associated-types/associated-types-in-fn.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass - -trait Get { - type Value; - fn get(&self) -> &::Value; -} - -struct Struct { - x: isize, -} - -impl Get for Struct { - type Value = isize; - fn get(&self) -> &isize { - &self.x - } -} - -fn grab(x: &T) -> &::Value { - x.get() -} - -fn main() { - let s = Struct { - x: 100, - }; - assert_eq!(*grab(&s), 100); -} diff --git a/src/test/run-pass/associated-types/associated-types-in-impl-generics.rs b/src/test/run-pass/associated-types/associated-types-in-impl-generics.rs deleted file mode 100644 index 0ddd99cbfa8..00000000000 --- a/src/test/run-pass/associated-types/associated-types-in-impl-generics.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass - -trait Get { - type Value; - fn get(&self) -> &::Value; -} - -struct Struct { - x: isize, -} - -impl Get for Struct { - type Value = isize; - fn get(&self) -> &isize { - &self.x - } -} - -trait Grab { - type U; - fn grab(&self) -> &::U; -} - -impl Grab for T { - type U = ::Value; - fn grab(&self) -> &::Value { - self.get() - } -} - -fn main() { - let s = Struct { - x: 100, - }; - assert_eq!(*s.grab(), 100); -} diff --git a/src/test/run-pass/associated-types/associated-types-in-inherent-method.rs b/src/test/run-pass/associated-types/associated-types-in-inherent-method.rs deleted file mode 100644 index 1f29e966851..00000000000 --- a/src/test/run-pass/associated-types/associated-types-in-inherent-method.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass - -trait Get { - type Value; - fn get(&self) -> &::Value; -} - -struct Struct { - x: isize, -} - -impl Get for Struct { - type Value = isize; - fn get(&self) -> &isize { - &self.x - } -} - -impl Struct { - fn grab(x: &T) -> &::Value { - x.get() - } -} - -fn main() { - let s = Struct { - x: 100, - }; - assert_eq!(*Struct::grab(&s), 100); -} diff --git a/src/test/run-pass/associated-types/associated-types-issue-20220.rs b/src/test/run-pass/associated-types/associated-types-issue-20220.rs deleted file mode 100644 index 19fa7a6085a..00000000000 --- a/src/test/run-pass/associated-types/associated-types-issue-20220.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// Test references to `Self::Item` in the trait. Issue #20220. - - -use std::vec; - -trait IntoIteratorX { - type Item; - type IntoIter: Iterator; - - fn into_iter_x(self) -> Self::IntoIter; -} - -impl IntoIteratorX for Vec { - type Item = T; - type IntoIter = vec::IntoIter; - - fn into_iter_x(self) -> vec::IntoIter { - self.into_iter() - } -} - -fn main() { - let vec = vec![1, 2, 3]; - for (i, e) in vec.into_iter().enumerate() { - assert_eq!(i+1, e); - } -} diff --git a/src/test/run-pass/associated-types/associated-types-issue-20371.rs b/src/test/run-pass/associated-types/associated-types-issue-20371.rs deleted file mode 100644 index ae8a8767d27..00000000000 --- a/src/test/run-pass/associated-types/associated-types-issue-20371.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// Test that we are able to have an impl that defines an associated type -// before the actual trait. - -// pretty-expanded FIXME #23616 - -impl X for f64 { type Y = isize; } -trait X { type Y; } -fn main() {} diff --git a/src/test/run-pass/associated-types/associated-types-issue-21212.rs b/src/test/run-pass/associated-types/associated-types-issue-21212.rs deleted file mode 100644 index ce27eac4d0e..00000000000 --- a/src/test/run-pass/associated-types/associated-types-issue-21212.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// Regression test for #21212: an overflow occurred during trait -// checking where normalizing `Self::Input` led to normalizing the -// where clauses in the environment which in turn required normalizing -// `Self::Input`. - - -pub trait Parser { - type Input; - - fn parse(input: ::Input) { - panic!() - } -} - -impl

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

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { - SliceExt2::split2(self, pred); - loop {} - } -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs deleted file mode 100644 index dcfae0f37e1..00000000000 --- a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// Test that we normalize associated types that appear in bounds; if -// we didn't, the call to `self.split2()` fails to type check. - -// pretty-expanded FIXME #23616 - -use std::marker::PhantomData; - -struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>); -struct SplitsN(PhantomData); - -trait SliceExt2 { - type Item; - - fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> - where P: FnMut(&Self::Item) -> bool; - fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN> - where P: FnMut(&Self::Item) -> bool; -} - -impl SliceExt2 for [T] { - type Item = T; - - fn split2

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

(&self, n: usize, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { - self.split2(pred); - loop {} - } -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs deleted file mode 100644 index a04525dcd46..00000000000 --- a/src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -// Regression test for issue #21010: Normalize associated types in -// various special paths in the `type_is_immediate` function. - -pub trait OffsetState: Sized {} -pub trait Offset { - type State: OffsetState; - fn dummy(&self) { } -} - -#[derive(Copy, Clone)] pub struct X; -impl Offset for X { type State = Y; } - -#[derive(Copy, Clone)] pub struct Y; -impl OffsetState for Y {} - -pub fn now() -> DateTime { from_utc(Y) } - -pub struct DateTime { pub offset: Off::State } -pub fn from_utc(offset: Off::State) -> DateTime { DateTime { offset: offset } } - -pub fn main() { - let _x = now(); -} diff --git a/src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs b/src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs deleted file mode 100644 index fc1dba97dfd..00000000000 --- a/src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs +++ /dev/null @@ -1,98 +0,0 @@ -// run-pass -// Various uses of `T::Item` syntax where the bound that supplies -// `Item` originates in a where-clause, not the declaration of -// `T`. Issue #20300. - -use std::marker::{PhantomData}; -use std::sync::atomic::{AtomicUsize}; -use std::sync::atomic::Ordering::SeqCst; - -static COUNTER: AtomicUsize = AtomicUsize::new(0); - -// Preamble. -trait Trait { type Item; } -struct Struct; -impl Trait for Struct { - type Item = u32; -} - -// Where-clause attached on the method which declares `T`. -struct A; -impl A { - fn foo(_x: T::Item) where T: Trait { - COUNTER.fetch_add(1, SeqCst); - } -} - -// Where-clause attached on the method to a parameter from the struct. -struct B(PhantomData); -impl B { - fn foo(_x: T::Item) where T: Trait { - COUNTER.fetch_add(10, SeqCst); - } -} - -// Where-clause attached to free fn. -fn c(_: T::Item) where T : Trait { - COUNTER.fetch_add(100, SeqCst); -} - -// Where-clause attached to defaulted and non-defaulted trait method. -trait AnotherTrait { - fn method(&self, _: T::Item) where T: Trait; - fn default_method(&self, _: T::Item) where T: Trait { - COUNTER.fetch_add(1000, SeqCst); - } -} -struct D; -impl AnotherTrait for D { - fn method(&self, _: T::Item) where T: Trait { - COUNTER.fetch_add(10000, SeqCst); - } -} - -// Where-clause attached to trait and impl containing the method. -trait YetAnotherTrait - where T : Trait -{ - fn method(&self, _: T::Item); - fn default_method(&self, _: T::Item) { - COUNTER.fetch_add(100000, SeqCst); - } -} -struct E(PhantomData); -impl YetAnotherTrait for E - where T : Trait -{ - fn method(&self, _: T::Item) { - COUNTER.fetch_add(1000000, SeqCst); - } -} - -// Where-clause attached to inherent impl containing the method. -struct F(PhantomData); -impl F where T : Trait { - fn method(&self, _: T::Item) { - COUNTER.fetch_add(10000000, SeqCst); - } -} - -// Where-clause attached to struct. -#[allow(dead_code)] -struct G where T : Trait { - data: T::Item, - phantom: PhantomData, -} - -fn main() { - A::foo::(22); - B::::foo(22); - c::(22); - D.method::(22); - D.default_method::(22); - E(PhantomData::).method(22); - E(PhantomData::).default_method(22); - F(PhantomData::).method(22); - G:: { data: 22, phantom: PhantomData }; - assert_eq!(COUNTER.load(SeqCst), 11111111); -} diff --git a/src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs b/src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs deleted file mode 100644 index 107e6b4ce0c..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// Test that we correctly handle projection bounds appearing in the -// supertrait list (and in conjunction with overloaded operators). In -// this case, the `Result=Self` binding in the supertrait listing of -// `Int` was being ignored. - -trait Not { - type Result; - - fn not(self) -> Self::Result; -} - -trait Int: Not + Sized { - fn count_ones(self) -> usize; - fn count_zeros(self) -> usize { - // neither works - let x: Self = self.not(); - 0 - } -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs deleted file mode 100644 index a59c327be21..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -// Test where the impl self type uses a projection from a constant type. - - -trait Int -{ - type T; - - fn dummy(&self) { } -} - -trait NonZero -{ - fn non_zero(self) -> bool; -} - -impl Int for i32 { type T = i32; } -impl Int for i64 { type T = i64; } -impl Int for u32 { type T = u32; } -impl Int for u64 { type T = u64; } - -impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } -impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } -impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } -impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } - -fn main () -{ - assert!(NonZero::non_zero(22_i32)); - assert!(NonZero::non_zero(22_i64)); - assert!(NonZero::non_zero(22_u32)); - assert!(NonZero::non_zero(22_u64)); - - assert!(!NonZero::non_zero(0_i32)); - assert!(!NonZero::non_zero(0_i64)); - assert!(!NonZero::non_zero(0_u32)); - assert!(!NonZero::non_zero(0_u64)); -} diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs deleted file mode 100644 index eec95a141f5..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs +++ /dev/null @@ -1,40 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_imports)] -// Corrected regression test for #20831. The original did not compile. -// When fixed, it revealed another problem concerning projections that -// appear in associated type bindings in object types, which were not -// being properly flagged. - -// pretty-expanded FIXME #23616 - -use std::ops::{Shl, Shr}; -use std::cell::RefCell; - -pub trait Subscriber { - type Input; - - fn dummy(&self) { } -} - -pub trait Publisher<'a> { - type Output; - fn subscribe(&mut self, _: Box + 'a>); -} - -pub trait Processor<'a> : Subscriber + Publisher<'a> { } - -impl<'a, P> Processor<'a> for P where P : Subscriber + Publisher<'a> { } - -struct MyStruct<'a> { - sub: Box + 'a> -} - -impl<'a> Publisher<'a> for MyStruct<'a> { - type Output = u64; - fn subscribe(&mut self, t : Box + 'a>) { - self.sub = t; - } -} - -fn main() {} diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs deleted file mode 100644 index ead405fcf01..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs +++ /dev/null @@ -1,45 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Test that we are handle to correctly handle a projection type -// that appears in a supertrait bound. Issue #20559. - - -trait A -{ - type TA; - - fn dummy(&self) { } -} - -trait B -{ - fn foo (&self, t : TB) -> String; -} - -trait C : B<::TA> { } - -struct X; - -impl A for X -{ - type TA = i32; -} - -struct Y; - -impl C for Y { } - -// Both of these impls are required for successful compilation -impl B for Y -{ - fn foo (&self, t : i32) -> String - { - format!("First {}", t) - } -} - -fn main () -{ - let y = Y; - assert_eq!(y.foo(5), format!("First 5")); -} diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs deleted file mode 100644 index e9a26e53c3c..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -// Test a where clause that uses a non-normalized projection type. - -// pretty-expanded FIXME #23616 - -trait Int -{ - type T; - - fn dummy(&self) { } -} - -trait NonZero -{ - fn non_zero(self) -> bool; -} - -fn foo,J>(t: I) -> bool - where ::T : NonZero - // ^~~~~~~~~~~~~ canonical form is just J -{ - bar::() -} - -fn bar() -> bool { true } - -fn main () -{ -} diff --git a/src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs b/src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs deleted file mode 100644 index 5f06a829600..00000000000 --- a/src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs deleted file mode 100644 index 3c830d37060..00000000000 --- a/src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -trait Foo { - type Bar; - fn get_bar() -> >::Bar; -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-ref-from-struct.rs b/src/test/run-pass/associated-types/associated-types-ref-from-struct.rs deleted file mode 100644 index 3ccba289e4b..00000000000 --- a/src/test/run-pass/associated-types/associated-types-ref-from-struct.rs +++ /dev/null @@ -1,55 +0,0 @@ -// run-pass -// Test associated type references in structure fields. - -// pretty-expanded FIXME #23616 - -trait Test { - type V; - - fn test(&self, value: &Self::V) -> bool; -} - -/////////////////////////////////////////////////////////////////////////// - -struct TesterPair { - tester: T, - value: T::V, -} - -impl TesterPair { - fn new(tester: T, value: T::V) -> TesterPair { - TesterPair { tester: tester, value: value } - } - - fn test(&self) -> bool { - self.tester.test(&self.value) - } -} - -/////////////////////////////////////////////////////////////////////////// - -struct EqU32(u32); -impl Test for EqU32 { - type V = u32; - - fn test(&self, value: &u32) -> bool { - self.0 == *value - } -} - -struct EqI32(i32); -impl Test for EqI32 { - type V = i32; - - fn test(&self, value: &i32) -> bool { - self.0 == *value - } -} - -fn main() { - let tester = TesterPair::new(EqU32(22), 23); - tester.test(); - - let tester = TesterPair::new(EqI32(22), 23); - tester.test(); -} diff --git a/src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs deleted file mode 100644 index 4a490ed0387..00000000000 --- a/src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -// Test associated type references in a struct literal. Issue #20535. - - -pub trait Foo { - type Bar; - - fn dummy(&self) { } -} - -impl Foo for isize { - type Bar = isize; -} - -struct Thing { - a: F, - b: F::Bar, -} - -fn main() { - let thing = Thing{a: 1, b: 2}; - assert_eq!(thing.a + 1, thing.b); -} diff --git a/src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs b/src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs deleted file mode 100644 index b722506dbbf..00000000000 --- a/src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Regression test for #20582. This test caused an ICE related to -// inconsistent region erasure in codegen. - -// pretty-expanded FIXME #23616 - -struct Foo<'a> { - buf: &'a[u8] -} - -impl<'a> Iterator for Foo<'a> { - type Item = &'a[u8]; - - fn next(&mut self) -> Option<::Item> { - Some(self.buf) - } -} - -fn main() { -} diff --git a/src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs deleted file mode 100644 index 52f2324d72a..00000000000 --- a/src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -trait Get { - fn get(&self) -> T; -} - -trait Trait<'a> { - type T: 'static; - type U: Get<&'a isize>; - - fn dummy(&'a self) { } -} - -fn main() {} diff --git a/src/test/run-pass/associated-types/associated-types-return.rs b/src/test/run-pass/associated-types/associated-types-return.rs deleted file mode 100644 index 997a48b0379..00000000000 --- a/src/test/run-pass/associated-types/associated-types-return.rs +++ /dev/null @@ -1,46 +0,0 @@ -// run-pass -// Test equality constraints on associated types in a where clause. - - -pub trait Foo { - type A; - fn boo(&self) -> ::A; -} - -#[derive(PartialEq, Debug)] -pub struct Bar; - -impl Foo for isize { - type A = usize; - fn boo(&self) -> usize { 42 } -} - -impl Foo for Bar { - type A = isize; - fn boo(&self) -> isize { 43 } -} - -impl Foo for char { - type A = Bar; - fn boo(&self) -> Bar { Bar } -} - -fn foo1>(x: I) -> Bar { - x.boo() -} - -fn foo2(x: I) -> ::A { - x.boo() -} - -pub fn main() { - let a = 42; - assert_eq!(foo2(a), 42); - - let a = Bar; - assert_eq!(foo2(a), 43); - - let a = 'a'; - foo1(a); - assert_eq!(foo2(a), Bar); -} diff --git a/src/test/run-pass/associated-types/associated-types-simple.rs b/src/test/run-pass/associated-types/associated-types-simple.rs deleted file mode 100644 index 2e2dfd80726..00000000000 --- a/src/test/run-pass/associated-types/associated-types-simple.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - -trait Get { - type Value; - fn get(&self) -> &::Value; -} - -struct Struct { - x: isize, -} - -impl Get for Struct { - type Value = isize; - fn get(&self) -> &isize { - &self.x - } -} - -fn main() { - let s = Struct { - x: 100, - }; - assert_eq!(*s.get(), 100); -} diff --git a/src/test/run-pass/associated-types/associated-types-stream.rs b/src/test/run-pass/associated-types/associated-types-stream.rs deleted file mode 100644 index 96954528aaa..00000000000 --- a/src/test/run-pass/associated-types/associated-types-stream.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass -// Test references to the trait `Stream` in the bounds for associated -// types defined on `Stream`. Issue #20551. - - -trait Stream { - type Car; - type Cdr: Stream; - - fn car(&self) -> Self::Car; - fn cdr(self) -> Self::Cdr; -} - -impl Stream for () { - type Car = (); - type Cdr = (); - fn car(&self) -> () { () } - fn cdr(self) -> () { self } -} - -impl Stream for (T, U) - where T : Clone, U : Stream -{ - type Car = T; - type Cdr = U; - fn car(&self) -> T { self.0.clone() } - fn cdr(self) -> U { self.1 } -} - -fn main() { - let p = (22, (44, (66, ()))); - assert_eq!(p.car(), 22); - - let p = p.cdr(); - assert_eq!(p.car(), 44); - - let p = p.cdr(); - assert_eq!(p.car(), 66); -} diff --git a/src/test/run-pass/associated-types/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types/associated-types-struct-field-named.rs deleted file mode 100644 index c400bf943e1..00000000000 --- a/src/test/run-pass/associated-types/associated-types-struct-field-named.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// Test that we correctly normalize the type of a struct field -// which has an associated type. - - -pub trait UnifyKey { - type Value; - - fn dummy(&self) { } -} - -pub struct Node { - pub key: K, - pub value: K::Value, -} - -fn foo>,V : Clone>(node: &Node) -> Option { - node.value.clone() -} - -impl UnifyKey for i32 { - type Value = Option; -} - -impl UnifyKey for u32 { - type Value = Option; -} - -pub fn main() { - let node: Node = Node { key: 1, value: Some(22) }; - assert_eq!(foo(&node), Some(22)); - - let node: Node = Node { key: 1, value: Some(22) }; - assert_eq!(foo(&node), Some(22)); -} diff --git a/src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs deleted file mode 100644 index fa59060629d..00000000000 --- a/src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/associated-types/associated-types-sugar-path.rs b/src/test/run-pass/associated-types/associated-types-sugar-path.rs deleted file mode 100644 index 66f7672aa43..00000000000 --- a/src/test/run-pass/associated-types/associated-types-sugar-path.rs +++ /dev/null @@ -1,41 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] -// Test paths to associated types using the type-parameter-only sugar. - -use std::ops::Deref; - -pub trait Foo { - type A; - fn boo(&self) -> Self::A; -} - -impl Foo for isize { - type A = usize; - fn boo(&self) -> usize { - 5 - } -} - -// Using a type via a function. -pub fn bar(a: T, x: T::A) -> T::A { - let _: T::A = a.boo(); - x -} - -// Using a type via an impl. -trait C { - fn f(); - fn g(&self) { } -} -struct B(X); -impl C for B { - fn f() { - let x: T::A = panic!(); - } -} - -pub fn main() { - let z: usize = bar(2, 4); -} diff --git a/src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs b/src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs deleted file mode 100644 index f2a4c6e42a9..00000000000 --- a/src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs +++ /dev/null @@ -1,46 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_imports)] -// Test how resolving a projection interacts with inference. In this -// case, we were eagerly unifying the type variable for the iterator -// type with `I` from the where clause, ignoring the in-scope `impl` -// for `ByRef`. The right answer was to consider the result ambiguous -// until more type information was available. - -#![feature(lang_items)] -#![no_implicit_prelude] - -use std::marker::Sized; -use std::option::Option::{None, Some, self}; - -trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} - -trait IteratorExt: Iterator + Sized { - fn by_ref(&mut self) -> ByRef { - ByRef(self) - } -} - -impl IteratorExt for I where I: Iterator {} - -struct ByRef<'a, I: 'a + Iterator>(&'a mut I); - -impl<'a, A, I> Iterator for ByRef<'a, I> where I: Iterator { - type Item = A; - - fn next(&mut self) -> Option< ::Item > { - self.0.next() - } -} - -fn is_iterator_of>(_: &I) {} - -fn test>(mut it: I) { - is_iterator_of::(&it.by_ref()); -} - -fn main() { } diff --git a/src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs b/src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs deleted file mode 100644 index b6785358706..00000000000 --- a/src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Helper for test issue-18048, which tests associated types in a -// cross-crate scenario. - -#![crate_type="lib"] - -pub trait Bar: Sized { - type T; - - fn get(x: Option) -> ::T; -} - -impl Bar for isize { - type T = usize; - - fn get(_: Option) -> usize { 22 } -} diff --git a/src/test/run-pass/atomic-access-bool.rs b/src/test/run-pass/atomic-access-bool.rs deleted file mode 100644 index e9d48bb3b43..00000000000 --- a/src/test/run-pass/atomic-access-bool.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/atomic-alignment.rs b/src/test/run-pass/atomic-alignment.rs deleted file mode 100644 index 5bda90d2eab..00000000000 --- a/src/test/run-pass/atomic-alignment.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/atomic-compare_exchange.rs b/src/test/run-pass/atomic-compare_exchange.rs deleted file mode 100644 index 9b327eef3c8..00000000000 --- a/src/test/run-pass/atomic-compare_exchange.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/atomic-print.rs b/src/test/run-pass/atomic-print.rs deleted file mode 100644 index ef3453da689..00000000000 --- a/src/test/run-pass/atomic-print.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/attr-main-2.rs b/src/test/run-pass/attr-main-2.rs deleted file mode 100644 index 3a51f83ba3b..00000000000 --- a/src/test/run-pass/attr-main-2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -#![feature(main)] - -pub fn main() { - panic!() -} - -#[main] -fn foo() { -} diff --git a/src/test/run-pass/attr-main.rs b/src/test/run-pass/attr-main.rs deleted file mode 100644 index 9c4caaa4a42..00000000000 --- a/src/test/run-pass/attr-main.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(main)] - -#[main] -fn foo() { -} diff --git a/src/test/run-pass/attr-shebang.rs b/src/test/run-pass/attr-shebang.rs deleted file mode 100644 index cce31c9bb7b..00000000000 --- a/src/test/run-pass/attr-shebang.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -#![allow(stable_features)] -#![feature(rust1)] -pub fn main() { } -// ignore-license diff --git a/src/test/run-pass/attr-start.rs b/src/test/run-pass/attr-start.rs deleted file mode 100644 index 6777631484b..00000000000 --- a/src/test/run-pass/attr-start.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(start)] - -#[start] -fn start(_argc: isize, _argv: *const *const u8) -> isize { - return 0; -} diff --git a/src/test/run-pass/attr.rs b/src/test/run-pass/attr.rs deleted file mode 100644 index 9c4caaa4a42..00000000000 --- a/src/test/run-pass/attr.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(main)] - -#[main] -fn foo() { -} diff --git a/src/test/run-pass/augmented-assignments-feature-gate-cross.rs b/src/test/run-pass/augmented-assignments-feature-gate-cross.rs deleted file mode 100644 index 84988feb6f5..00000000000 --- a/src/test/run-pass/augmented-assignments-feature-gate-cross.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/augmented-assignments-feature-gate.rs b/src/test/run-pass/augmented-assignments-feature-gate.rs deleted file mode 100644 index 8e686796fee..00000000000 --- a/src/test/run-pass/augmented-assignments-feature-gate.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/auto-instantiate.rs b/src/test/run-pass/auto-instantiate.rs deleted file mode 100644 index a58b178287f..00000000000 --- a/src/test/run-pass/auto-instantiate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/auto-is-contextual.rs b/src/test/run-pass/auto-is-contextual.rs deleted file mode 100644 index a2ddd5374c0..00000000000 --- a/src/test/run-pass/auto-is-contextual.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/autobind.rs b/src/test/run-pass/autobind.rs deleted file mode 100644 index 70606a2a200..00000000000 --- a/src/test/run-pass/autobind.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs b/src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs deleted file mode 100644 index 2482e1878f5..00000000000 --- a/src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs b/src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs deleted file mode 100644 index e5f79d78051..00000000000 --- a/src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/auto-ref.rs b/src/test/run-pass/autoref-autoderef/auto-ref.rs deleted file mode 100644 index b77f9c34213..00000000000 --- a/src/test/run-pass/autoref-autoderef/auto-ref.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs deleted file mode 100644 index 874f4228277..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs b/src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs deleted file mode 100644 index fadb0784e75..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs b/src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs deleted file mode 100644 index a218f85eba2..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs b/src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs deleted file mode 100644 index 9fda3b2c099..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs b/src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs deleted file mode 100644 index f53dc8d1032..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-method.rs b/src/test/run-pass/autoref-autoderef/autoderef-method.rs deleted file mode 100644 index 262050fa47b..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-method.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoderef-privacy.rs b/src/test/run-pass/autoref-autoderef/autoderef-privacy.rs deleted file mode 100644 index 841be930b77..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoderef-privacy.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs b/src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs deleted file mode 100644 index 70ef7ce87ed..00000000000 --- a/src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688eb..00000000000 --- a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![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/src/test/run-pass/auxiliary/augmented_assignments.rs b/src/test/run-pass/auxiliary/augmented_assignments.rs deleted file mode 100644 index d0d3f57459a..00000000000 --- a/src/test/run-pass/auxiliary/augmented_assignments.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::ops::AddAssign; - -pub struct Int(pub i32); - -impl AddAssign for Int { - fn add_assign(&mut self, _: i32) { - } -} diff --git a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs b/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs deleted file mode 100644 index cf769f31bf7..00000000000 --- a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type="lib"] - -pub const X: () = (); diff --git a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs deleted file mode 100644 index 81c16ede909..00000000000 --- a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type="lib"] - -pub const Y: () = (); diff --git a/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs deleted file mode 100644 index 5330b7a92a3..00000000000 --- a/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/auxiliary/cond_plugin.rs b/src/test/run-pass/auxiliary/cond_plugin.rs deleted file mode 100644 index 1f97b556a07..00000000000 --- a/src/test/run-pass/auxiliary/cond_plugin.rs +++ /dev/null @@ -1,38 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs deleted file mode 100644 index d08504005a5..00000000000 --- a/src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![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/src/test/run-pass/auxiliary/debuginfo-lto-aux.rs b/src/test/run-pass/auxiliary/debuginfo-lto-aux.rs deleted file mode 100644 index dd471154b4f..00000000000 --- a/src/test/run-pass/auxiliary/debuginfo-lto-aux.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/auxiliary/edition-kw-macro-2015.rs b/src/test/run-pass/auxiliary/edition-kw-macro-2015.rs deleted file mode 100644 index 553ba69303a..00000000000 --- a/src/test/run-pass/auxiliary/edition-kw-macro-2015.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/auxiliary/edition-kw-macro-2018.rs b/src/test/run-pass/auxiliary/edition-kw-macro-2018.rs deleted file mode 100644 index f1f4ee28093..00000000000 --- a/src/test/run-pass/auxiliary/edition-kw-macro-2018.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/auxiliary/foreign_lib.rs b/src/test/run-pass/auxiliary/foreign_lib.rs deleted file mode 100644 index de6b0e2118a..00000000000 --- a/src/test/run-pass/auxiliary/foreign_lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![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/src/test/run-pass/auxiliary/hello_macro.rs b/src/test/run-pass/auxiliary/hello_macro.rs deleted file mode 100644 index f2e9e0eaa8c..00000000000 --- a/src/test/run-pass/auxiliary/hello_macro.rs +++ /dev/null @@ -1,21 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![feature(proc_macro_hygiene, 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/src/test/run-pass/auxiliary/impl_privacy_xc_1.rs b/src/test/run-pass/auxiliary/impl_privacy_xc_1.rs deleted file mode 100644 index 367b8ec8b88..00000000000 --- a/src/test/run-pass/auxiliary/impl_privacy_xc_1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_type = "lib"] - -pub struct Fish { - pub x: isize -} - -impl Fish { - pub fn swim(&self) {} -} diff --git a/src/test/run-pass/auxiliary/impl_privacy_xc_2.rs b/src/test/run-pass/auxiliary/impl_privacy_xc_2.rs deleted file mode 100644 index 5f9c2268167..00000000000 --- a/src/test/run-pass/auxiliary/impl_privacy_xc_2.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![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/src/test/run-pass/auxiliary/inline_dtor.rs b/src/test/run-pass/auxiliary/inline_dtor.rs deleted file mode 100644 index 5eee89fdc57..00000000000 --- a/src/test/run-pass/auxiliary/inline_dtor.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![crate_name="inline_dtor"] - -pub struct Foo; - -impl Drop for Foo { - #[inline] - fn drop(&mut self) {} -} diff --git a/src/test/run-pass/auxiliary/inner_static.rs b/src/test/run-pass/auxiliary/inner_static.rs deleted file mode 100644 index 42dcd379d41..00000000000 --- a/src/test/run-pass/auxiliary/inner_static.rs +++ /dev/null @@ -1,51 +0,0 @@ -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/src/test/run-pass/auxiliary/kinds_in_metadata.rs b/src/test/run-pass/auxiliary/kinds_in_metadata.rs deleted file mode 100644 index 2a2106ff70a..00000000000 --- a/src/test/run-pass/auxiliary/kinds_in_metadata.rs +++ /dev/null @@ -1,8 +0,0 @@ -/* 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/src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs b/src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs deleted file mode 100644 index fa4f33bcef6..00000000000 --- a/src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(link_cfg)] - -#[link(name = "foo", cfg(foo))] -extern {} diff --git a/src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs b/src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs deleted file mode 100644 index b365ed91732..00000000000 --- a/src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs +++ /dev/null @@ -1,7 +0,0 @@ -// no-prefer-dynamic - -#![feature(link_cfg)] -#![crate_type = "rlib"] - -#[link(name = "foo", cfg(foo))] -extern {} diff --git a/src/test/run-pass/auxiliary/linkage1.rs b/src/test/run-pass/auxiliary/linkage1.rs deleted file mode 100644 index e87ce5e4d31..00000000000 --- a/src/test/run-pass/auxiliary/linkage1.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[no_mangle] -pub static foo: isize = 3; - -pub fn bar() {} diff --git a/src/test/run-pass/auxiliary/llvm_pr32379.rs b/src/test/run-pass/auxiliary/llvm_pr32379.rs deleted file mode 100644 index 8e429767095..00000000000 --- a/src/test/run-pass/auxiliary/llvm_pr32379.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub fn pr32379(mut data: u64, f1: bool, f2: bool) -> u64 { - if f1 { data &= !2; } - if f2 { data |= 2; } - data -} diff --git a/src/test/run-pass/auxiliary/msvc-data-only-lib.rs b/src/test/run-pass/auxiliary/msvc-data-only-lib.rs deleted file mode 100644 index ccaa6d8edcf..00000000000 --- a/src/test/run-pass/auxiliary/msvc-data-only-lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -pub static FOO: i32 = 42; diff --git a/src/test/run-pass/auxiliary/nested_item.rs b/src/test/run-pass/auxiliary/nested_item.rs deleted file mode 100644 index 9db9d19d6f6..00000000000 --- a/src/test/run-pass/auxiliary/nested_item.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/auxiliary/proc_macro_def.rs b/src/test/run-pass/auxiliary/proc_macro_def.rs deleted file mode 100644 index dfc5a42d19c..00000000000 --- a/src/test/run-pass/auxiliary/proc_macro_def.rs +++ /dev/null @@ -1,35 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/auxiliary/reachable-unnameable-items.rs b/src/test/run-pass/auxiliary/reachable-unnameable-items.rs deleted file mode 100644 index 20f110b1a8c..00000000000 --- a/src/test/run-pass/auxiliary/reachable-unnameable-items.rs +++ /dev/null @@ -1,106 +0,0 @@ -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/src/test/run-pass/auxiliary/reexport-should-still-link.rs b/src/test/run-pass/auxiliary/reexport-should-still-link.rs deleted file mode 100644 index 237ea8dfcf3..00000000000 --- a/src/test/run-pass/auxiliary/reexport-should-still-link.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use foo::bar; - -mod foo { - pub fn bar() {} -} diff --git a/src/test/run-pass/auxiliary/rmeta-rmeta.rs b/src/test/run-pass/auxiliary/rmeta-rmeta.rs deleted file mode 100644 index 4a6d055a81f..00000000000 --- a/src/test/run-pass/auxiliary/rmeta-rmeta.rs +++ /dev/null @@ -1,9 +0,0 @@ -// no-prefer-dynamic -// compile-flags: --emit=metadata - -#![crate_type="rlib"] -#![crate_name="rmeta_aux"] - -pub struct Foo { - pub field2: i32, -} diff --git a/src/test/run-pass/auxiliary/svh-a-base.rs b/src/test/run-pass/auxiliary/svh-a-base.rs deleted file mode 100644 index 36b41fc818f..00000000000 --- a/src/test/run-pass/auxiliary/svh-a-base.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! 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/src/test/run-pass/auxiliary/svh-b.rs b/src/test/run-pass/auxiliary/svh-b.rs deleted file mode 100644 index 57029f70888..00000000000 --- a/src/test/run-pass/auxiliary/svh-b.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! 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/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs b/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs deleted file mode 100644 index acfd1e13e93..00000000000 --- a/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs deleted file mode 100644 index 281c079682f..00000000000 --- a/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs +++ /dev/null @@ -1,29 +0,0 @@ -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/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs deleted file mode 100644 index 281c079682f..00000000000 --- a/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs +++ /dev/null @@ -1,29 +0,0 @@ -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/src/test/run-pass/auxiliary/using-target-feature-unstable.rs b/src/test/run-pass/auxiliary/using-target-feature-unstable.rs deleted file mode 100644 index 78645c284f1..00000000000 --- a/src/test/run-pass/auxiliary/using-target-feature-unstable.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(mmx_target_feature)] - -#[inline] -#[target_feature(enable = "mmx")] -pub unsafe fn foo() {} diff --git a/src/test/run-pass/backtrace-debuginfo-aux.rs b/src/test/run-pass/backtrace-debuginfo-aux.rs deleted file mode 100644 index 1411bcf89e8..00000000000 --- a/src/test/run-pass/backtrace-debuginfo-aux.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs deleted file mode 100644 index 8668ec82bfd..00000000000 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ /dev/null @@ -1,180 +0,0 @@ -// 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-msvc issue #62844 -// 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. - if cfg!(any(target_os = "android", - all(target_os = "linux", target_arch = "arm"), - 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/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs deleted file mode 100644 index 82519332d64..00000000000 --- a/src/test/run-pass/backtrace.rs +++ /dev/null @@ -1,125 +0,0 @@ -// 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-msvc issue #62844 -// ignore-sgx no processes -// 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/src/test/run-pass/bare-fn-implements-fn-mut.rs b/src/test/run-pass/bare-fn-implements-fn-mut.rs deleted file mode 100644 index dfead48893e..00000000000 --- a/src/test/run-pass/bare-fn-implements-fn-mut.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/bare-static-string.rs b/src/test/run-pass/bare-static-string.rs deleted file mode 100644 index d336dc7c6a0..00000000000 --- a/src/test/run-pass/bare-static-string.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -pub fn main() { - let x: &'static str = "foo"; - println!("{}", x); -} diff --git a/src/test/run-pass/bench/issue-32062.rs b/src/test/run-pass/bench/issue-32062.rs deleted file mode 100644 index dc45061da5b..00000000000 --- a/src/test/run-pass/bench/issue-32062.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/big-literals.rs b/src/test/run-pass/big-literals.rs deleted file mode 100644 index 131de5439b7..00000000000 --- a/src/test/run-pass/big-literals.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binary-minus-without-space.rs b/src/test/run-pass/binary-minus-without-space.rs deleted file mode 100644 index 2fbd5300dd1..00000000000 --- a/src/test/run-pass/binary-minus-without-space.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// Check that issue #954 stays fixed - - -pub fn main() { - match -1 { -1 => {}, _ => panic!("wat") } - assert_eq!(1-1, 0); -} diff --git a/src/test/run-pass/bind-by-move.rs b/src/test/run-pass/bind-by-move.rs deleted file mode 100644 index f0a9ebdd08c..00000000000 --- a/src/test/run-pass/bind-by-move.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/bind-field-short-with-modifiers.rs b/src/test/run-pass/binding/bind-field-short-with-modifiers.rs deleted file mode 100644 index b271f84e9ce..00000000000 --- a/src/test/run-pass/binding/bind-field-short-with-modifiers.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/binding/borrowed-ptr-pattern-2.rs b/src/test/run-pass/binding/borrowed-ptr-pattern-2.rs deleted file mode 100644 index 40df85b1479..00000000000 --- a/src/test/run-pass/binding/borrowed-ptr-pattern-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/borrowed-ptr-pattern-3.rs b/src/test/run-pass/binding/borrowed-ptr-pattern-3.rs deleted file mode 100644 index f2607eee815..00000000000 --- a/src/test/run-pass/binding/borrowed-ptr-pattern-3.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs b/src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs deleted file mode 100644 index 1bbc03e19ba..00000000000 --- a/src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - - -pub fn main() { - let (&x, &y) = (&3, &'a'); - assert_eq!(x, 3); - assert_eq!(y, 'a'); -} diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern-option.rs b/src/test/run-pass/binding/borrowed-ptr-pattern-option.rs deleted file mode 100644 index 319b8631e8d..00000000000 --- a/src/test/run-pass/binding/borrowed-ptr-pattern-option.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/binding/borrowed-ptr-pattern.rs b/src/test/run-pass/binding/borrowed-ptr-pattern.rs deleted file mode 100644 index d5f94ab54e3..00000000000 --- a/src/test/run-pass/binding/borrowed-ptr-pattern.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/empty-types-in-patterns.rs b/src/test/run-pass/binding/empty-types-in-patterns.rs deleted file mode 100644 index 2b8b1b29df8..00000000000 --- a/src/test/run-pass/binding/empty-types-in-patterns.rs +++ /dev/null @@ -1,58 +0,0 @@ -// run-pass -#![feature(never_type)] -#![feature(exhaustive_patterns)] -#![feature(slice_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/src/test/run-pass/binding/exhaustive-bool-match-sanity.rs b/src/test/run-pass/binding/exhaustive-bool-match-sanity.rs deleted file mode 100644 index f83def21060..00000000000 --- a/src/test/run-pass/binding/exhaustive-bool-match-sanity.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-generic-unique1.rs b/src/test/run-pass/binding/expr-match-generic-unique1.rs deleted file mode 100644 index 5a5f75eea36..00000000000 --- a/src/test/run-pass/binding/expr-match-generic-unique1.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-generic-unique2.rs b/src/test/run-pass/binding/expr-match-generic-unique2.rs deleted file mode 100644 index 1d236135cdb..00000000000 --- a/src/test/run-pass/binding/expr-match-generic-unique2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-generic.rs b/src/test/run-pass/binding/expr-match-generic.rs deleted file mode 100644 index 530fc676f7c..00000000000 --- a/src/test/run-pass/binding/expr-match-generic.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-panic-all.rs b/src/test/run-pass/binding/expr-match-panic-all.rs deleted file mode 100644 index ac31b49a1e9..00000000000 --- a/src/test/run-pass/binding/expr-match-panic-all.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-panic.rs b/src/test/run-pass/binding/expr-match-panic.rs deleted file mode 100644 index 4b6b6e072c0..00000000000 --- a/src/test/run-pass/binding/expr-match-panic.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match-unique.rs b/src/test/run-pass/binding/expr-match-unique.rs deleted file mode 100644 index a999541207d..00000000000 --- a/src/test/run-pass/binding/expr-match-unique.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/binding/expr-match.rs b/src/test/run-pass/binding/expr-match.rs deleted file mode 100644 index 575b38fbc95..00000000000 --- a/src/test/run-pass/binding/expr-match.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/binding/fat-arrow-match.rs b/src/test/run-pass/binding/fat-arrow-match.rs deleted file mode 100644 index aaf5be8cf74..00000000000 --- a/src/test/run-pass/binding/fat-arrow-match.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs deleted file mode 100644 index ea4a9e5afa5..00000000000 --- a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs +++ /dev/null @@ -1,69 +0,0 @@ -// 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/src/test/run-pass/binding/fn-pattern-expected-type-2.rs b/src/test/run-pass/binding/fn-pattern-expected-type-2.rs deleted file mode 100644 index 130ff3d4465..00000000000 --- a/src/test/run-pass/binding/fn-pattern-expected-type-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/binding/fn-pattern-expected-type.rs b/src/test/run-pass/binding/fn-pattern-expected-type.rs deleted file mode 100644 index faeb7649636..00000000000 --- a/src/test/run-pass/binding/fn-pattern-expected-type.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/binding/func-arg-incomplete-pattern.rs b/src/test/run-pass/binding/func-arg-incomplete-pattern.rs deleted file mode 100644 index 98dd51811de..00000000000 --- a/src/test/run-pass/binding/func-arg-incomplete-pattern.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/binding/func-arg-ref-pattern.rs b/src/test/run-pass/binding/func-arg-ref-pattern.rs deleted file mode 100644 index ebb7a6afa9b..00000000000 --- a/src/test/run-pass/binding/func-arg-ref-pattern.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// exec-env:RUST_POISON_ON_FREE=1 - -// 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/src/test/run-pass/binding/func-arg-wild-pattern.rs b/src/test/run-pass/binding/func-arg-wild-pattern.rs deleted file mode 100644 index bcd82c679a5..00000000000 --- a/src/test/run-pass/binding/func-arg-wild-pattern.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/if-let.rs b/src/test/run-pass/binding/if-let.rs deleted file mode 100644 index 3ea8d402a3e..00000000000 --- a/src/test/run-pass/binding/if-let.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs b/src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs deleted file mode 100644 index 87768c28cf4..00000000000 --- a/src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs b/src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs deleted file mode 100644 index 079cc0a16db..00000000000 --- a/src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/binding/irrefutable-slice-patterns.rs b/src/test/run-pass/binding/irrefutable-slice-patterns.rs deleted file mode 100644 index 733e6b7b57f..00000000000 --- a/src/test/run-pass/binding/irrefutable-slice-patterns.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// #47096 - -#![feature(slice_patterns)] - -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/src/test/run-pass/binding/let-assignability.rs b/src/test/run-pass/binding/let-assignability.rs deleted file mode 100644 index 5bb375d285d..00000000000 --- a/src/test/run-pass/binding/let-assignability.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/let-destruct-ref.rs b/src/test/run-pass/binding/let-destruct-ref.rs deleted file mode 100644 index 28d7294ebc8..00000000000 --- a/src/test/run-pass/binding/let-destruct-ref.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let x = 3_usize; - let ref y = x; - assert_eq!(x, *y); -} diff --git a/src/test/run-pass/binding/let-var-hygiene.rs b/src/test/run-pass/binding/let-var-hygiene.rs deleted file mode 100644 index 571207bd7d6..00000000000 --- a/src/test/run-pass/binding/let-var-hygiene.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/binding/match-arm-statics.rs b/src/test/run-pass/binding/match-arm-statics.rs deleted file mode 100644 index 5f7e357eeb2..00000000000 --- a/src/test/run-pass/binding/match-arm-statics.rs +++ /dev/null @@ -1,164 +0,0 @@ -// run-pass -#![allow(dead_code)] -// compile-flags: -g - -#[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/src/test/run-pass/binding/match-beginning-vert.rs b/src/test/run-pass/binding/match-beginning-vert.rs deleted file mode 100644 index 79267400b28..00000000000 --- a/src/test/run-pass/binding/match-beginning-vert.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/binding/match-borrowed_str.rs b/src/test/run-pass/binding/match-borrowed_str.rs deleted file mode 100644 index 22782032ebf..00000000000 --- a/src/test/run-pass/binding/match-borrowed_str.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/binding/match-bot-2.rs b/src/test/run-pass/binding/match-bot-2.rs deleted file mode 100644 index 95b3406f0b5..00000000000 --- a/src/test/run-pass/binding/match-bot-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -// 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/src/test/run-pass/binding/match-bot.rs b/src/test/run-pass/binding/match-bot.rs deleted file mode 100644 index 5c4472c7aea..00000000000 --- a/src/test/run-pass/binding/match-bot.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let i: isize = - match Some::(3) { None:: => { panic!() } Some::(_) => { 5 } }; - println!("{}", i); -} diff --git a/src/test/run-pass/binding/match-byte-array-patterns.rs b/src/test/run-pass/binding/match-byte-array-patterns.rs deleted file mode 100644 index e87745705da..00000000000 --- a/src/test/run-pass/binding/match-byte-array-patterns.rs +++ /dev/null @@ -1,45 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/binding/match-enum-struct-0.rs b/src/test/run-pass/binding/match-enum-struct-0.rs deleted file mode 100644 index e2623ece84c..00000000000 --- a/src/test/run-pass/binding/match-enum-struct-0.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/match-enum-struct-1.rs b/src/test/run-pass/binding/match-enum-struct-1.rs deleted file mode 100644 index f035432ec99..00000000000 --- a/src/test/run-pass/binding/match-enum-struct-1.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/binding/match-implicit-copy-unique.rs b/src/test/run-pass/binding/match-implicit-copy-unique.rs deleted file mode 100644 index a7e8109b46c..00000000000 --- a/src/test/run-pass/binding/match-implicit-copy-unique.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/match-in-macro.rs b/src/test/run-pass/binding/match-in-macro.rs deleted file mode 100644 index 0840cc4404d..00000000000 --- a/src/test/run-pass/binding/match-in-macro.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/match-join.rs b/src/test/run-pass/binding/match-join.rs deleted file mode 100644 index 60f2a458489..00000000000 --- a/src/test/run-pass/binding/match-join.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/binding/match-larger-const.rs b/src/test/run-pass/binding/match-larger-const.rs deleted file mode 100644 index 6f9a353207f..00000000000 --- a/src/test/run-pass/binding/match-larger-const.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/match-naked-record-expr.rs b/src/test/run-pass/binding/match-naked-record-expr.rs deleted file mode 100644 index c23ff8c9495..00000000000 --- a/src/test/run-pass/binding/match-naked-record-expr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -struct X { x: isize } - -pub fn main() { - let _x = match 0 { - _ => X { - x: 0 - }.x - }; -} diff --git a/src/test/run-pass/binding/match-naked-record.rs b/src/test/run-pass/binding/match-naked-record.rs deleted file mode 100644 index f7479152ebc..00000000000 --- a/src/test/run-pass/binding/match-naked-record.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/match-path.rs b/src/test/run-pass/binding/match-path.rs deleted file mode 100644 index 286214eb8ac..00000000000 --- a/src/test/run-pass/binding/match-path.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/match-pattern-bindings.rs b/src/test/run-pass/binding/match-pattern-bindings.rs deleted file mode 100644 index 4ec533677d6..00000000000 --- a/src/test/run-pass/binding/match-pattern-bindings.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/binding/match-pattern-lit.rs b/src/test/run-pass/binding/match-pattern-lit.rs deleted file mode 100644 index c9c6135e2e6..00000000000 --- a/src/test/run-pass/binding/match-pattern-lit.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/binding/match-pattern-no-type-params.rs b/src/test/run-pass/binding/match-pattern-no-type-params.rs deleted file mode 100644 index 1fc7ddda023..00000000000 --- a/src/test/run-pass/binding/match-pattern-no-type-params.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/match-pattern-simple.rs b/src/test/run-pass/binding/match-pattern-simple.rs deleted file mode 100644 index 3f56cd4796d..00000000000 --- a/src/test/run-pass/binding/match-pattern-simple.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(dead_code)] - - -// pretty-expanded FIXME #23616 - -fn altsimple(f: isize) { match f { _x => () } } - -pub fn main() { } diff --git a/src/test/run-pass/binding/match-phi.rs b/src/test/run-pass/binding/match-phi.rs deleted file mode 100644 index 92a3f6e0f7f..00000000000 --- a/src/test/run-pass/binding/match-phi.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/binding/match-pipe-binding.rs b/src/test/run-pass/binding/match-pipe-binding.rs deleted file mode 100644 index 7d4a7c708dd..00000000000 --- a/src/test/run-pass/binding/match-pipe-binding.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/binding/match-range-infer.rs b/src/test/run-pass/binding/match-range-infer.rs deleted file mode 100644 index 19d1cb89d4a..00000000000 --- a/src/test/run-pass/binding/match-range-infer.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/match-range-static.rs b/src/test/run-pass/binding/match-range-static.rs deleted file mode 100644 index f01a3505ee6..00000000000 --- a/src/test/run-pass/binding/match-range-static.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/match-range.rs b/src/test/run-pass/binding/match-range.rs deleted file mode 100644 index 1dca84dfd45..00000000000 --- a/src/test/run-pass/binding/match-range.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/binding/match-reassign.rs b/src/test/run-pass/binding/match-reassign.rs deleted file mode 100644 index 19b48579cb4..00000000000 --- a/src/test/run-pass/binding/match-reassign.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs b/src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs deleted file mode 100644 index 9075a34d410..00000000000 --- a/src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/match-ref-binding-mut-option.rs b/src/test/run-pass/binding/match-ref-binding-mut-option.rs deleted file mode 100644 index c25639b7213..00000000000 --- a/src/test/run-pass/binding/match-ref-binding-mut-option.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/binding/match-ref-binding-mut.rs b/src/test/run-pass/binding/match-ref-binding-mut.rs deleted file mode 100644 index d7afd61bc8e..00000000000 --- a/src/test/run-pass/binding/match-ref-binding-mut.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/binding/match-ref-binding.rs b/src/test/run-pass/binding/match-ref-binding.rs deleted file mode 100644 index ac6a07eabe1..00000000000 --- a/src/test/run-pass/binding/match-ref-binding.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/match-ref-unsized.rs b/src/test/run-pass/binding/match-ref-unsized.rs deleted file mode 100644 index 53784ebb9fc..00000000000 --- a/src/test/run-pass/binding/match-ref-unsized.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/binding/match-str.rs b/src/test/run-pass/binding/match-str.rs deleted file mode 100644 index 0ee18ea18de..00000000000 --- a/src/test/run-pass/binding/match-str.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/binding/match-struct-0.rs b/src/test/run-pass/binding/match-struct-0.rs deleted file mode 100644 index c49f3ed6178..00000000000 --- a/src/test/run-pass/binding/match-struct-0.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/binding/match-tag.rs b/src/test/run-pass/binding/match-tag.rs deleted file mode 100644 index eceb6467784..00000000000 --- a/src/test/run-pass/binding/match-tag.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/binding/match-unique-bind.rs b/src/test/run-pass/binding/match-unique-bind.rs deleted file mode 100644 index f5361b118be..00000000000 --- a/src/test/run-pass/binding/match-unique-bind.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/match-unsized.rs b/src/test/run-pass/binding/match-unsized.rs deleted file mode 100644 index 41937a557ef..00000000000 --- a/src/test/run-pass/binding/match-unsized.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -fn main() { - let data: &'static str = "Hello, World!"; - match data { - &ref xs => { - assert_eq!(data, xs); - } - } -} diff --git a/src/test/run-pass/binding/match-value-binding-in-guard-3291.rs b/src/test/run-pass/binding/match-value-binding-in-guard-3291.rs deleted file mode 100644 index 4b209b20a18..00000000000 --- a/src/test/run-pass/binding/match-value-binding-in-guard-3291.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/binding/match-var-hygiene.rs b/src/test/run-pass/binding/match-var-hygiene.rs deleted file mode 100644 index 43740bbcf1d..00000000000 --- a/src/test/run-pass/binding/match-var-hygiene.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/binding/match-vec-alternatives.rs b/src/test/run-pass/binding/match-vec-alternatives.rs deleted file mode 100644 index 9b06a86a7b9..00000000000 --- a/src/test/run-pass/binding/match-vec-alternatives.rs +++ /dev/null @@ -1,81 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/binding/match-vec-rvalue.rs b/src/test/run-pass/binding/match-vec-rvalue.rs deleted file mode 100644 index fead2254c75..00000000000 --- a/src/test/run-pass/binding/match-vec-rvalue.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/binding/match-with-ret-arm.rs b/src/test/run-pass/binding/match-with-ret-arm.rs deleted file mode 100644 index 58a90964121..00000000000 --- a/src/test/run-pass/binding/match-with-ret-arm.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/binding/multi-let.rs b/src/test/run-pass/binding/multi-let.rs deleted file mode 100644 index 064d32a7084..00000000000 --- a/src/test/run-pass/binding/multi-let.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let x = 10; - let y = x; - assert_eq!(y, 10); -} diff --git a/src/test/run-pass/binding/mut-in-ident-patterns.rs b/src/test/run-pass/binding/mut-in-ident-patterns.rs deleted file mode 100644 index 1d1dd660e51..00000000000 --- a/src/test/run-pass/binding/mut-in-ident-patterns.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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/src/test/run-pass/binding/nested-exhaustive-match.rs b/src/test/run-pass/binding/nested-exhaustive-match.rs deleted file mode 100644 index 8b2294f8432..00000000000 --- a/src/test/run-pass/binding/nested-exhaustive-match.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/nested-matchs.rs b/src/test/run-pass/binding/nested-matchs.rs deleted file mode 100644 index 29490fd4888..00000000000 --- a/src/test/run-pass/binding/nested-matchs.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/binding/nested-pattern.rs b/src/test/run-pass/binding/nested-pattern.rs deleted file mode 100644 index 7d14c9ad9b7..00000000000 --- a/src/test/run-pass/binding/nested-pattern.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/binding/nil-pattern.rs b/src/test/run-pass/binding/nil-pattern.rs deleted file mode 100644 index 268af351d08..00000000000 --- a/src/test/run-pass/binding/nil-pattern.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { let x = (); match x { () => { } } } diff --git a/src/test/run-pass/binding/nullary-or-pattern.rs b/src/test/run-pass/binding/nullary-or-pattern.rs deleted file mode 100644 index 7a3d9d60eda..00000000000 --- a/src/test/run-pass/binding/nullary-or-pattern.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/binding/optional_comma_in_match_arm.rs b/src/test/run-pass/binding/optional_comma_in_match_arm.rs deleted file mode 100644 index fc268bf2a45..00000000000 --- a/src/test/run-pass/binding/optional_comma_in_match_arm.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/binding/or-pattern.rs b/src/test/run-pass/binding/or-pattern.rs deleted file mode 100644 index 2ab44a96c3a..00000000000 --- a/src/test/run-pass/binding/or-pattern.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/order-drop-with-match.rs b/src/test/run-pass/binding/order-drop-with-match.rs deleted file mode 100644 index f50632ede9f..00000000000 --- a/src/test/run-pass/binding/order-drop-with-match.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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/src/test/run-pass/binding/pat-ranges.rs b/src/test/run-pass/binding/pat-ranges.rs deleted file mode 100644 index 19b3045784f..00000000000 --- a/src/test/run-pass/binding/pat-ranges.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-1.rs b/src/test/run-pass/binding/pat-tuple-1.rs deleted file mode 100644 index b09d4a22df0..00000000000 --- a/src/test/run-pass/binding/pat-tuple-1.rs +++ /dev/null @@ -1,93 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-2.rs b/src/test/run-pass/binding/pat-tuple-2.rs deleted file mode 100644 index 810fd264139..00000000000 --- a/src/test/run-pass/binding/pat-tuple-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-3.rs b/src/test/run-pass/binding/pat-tuple-3.rs deleted file mode 100644 index 9bec898611e..00000000000 --- a/src/test/run-pass/binding/pat-tuple-3.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-4.rs b/src/test/run-pass/binding/pat-tuple-4.rs deleted file mode 100644 index 71a54850268..00000000000 --- a/src/test/run-pass/binding/pat-tuple-4.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-5.rs b/src/test/run-pass/binding/pat-tuple-5.rs deleted file mode 100644 index c8cdd37dd85..00000000000 --- a/src/test/run-pass/binding/pat-tuple-5.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-6.rs b/src/test/run-pass/binding/pat-tuple-6.rs deleted file mode 100644 index 877f0e4140e..00000000000 --- a/src/test/run-pass/binding/pat-tuple-6.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/binding/pat-tuple-7.rs b/src/test/run-pass/binding/pat-tuple-7.rs deleted file mode 100644 index 7835e2c352f..00000000000 --- a/src/test/run-pass/binding/pat-tuple-7.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -fn main() { - #[allow(unused_parens)] - match 0 { - (pat) => assert_eq!(pat, 0) - } -} diff --git a/src/test/run-pass/binding/pattern-bound-var-in-for-each.rs b/src/test/run-pass/binding/pattern-bound-var-in-for-each.rs deleted file mode 100644 index 3f725cddc5b..00000000000 --- a/src/test/run-pass/binding/pattern-bound-var-in-for-each.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/binding/pattern-in-closure.rs b/src/test/run-pass/binding/pattern-in-closure.rs deleted file mode 100644 index 3ac8d57681a..00000000000 --- a/src/test/run-pass/binding/pattern-in-closure.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/binding/range-inclusive-pattern-precedence.rs b/src/test/run-pass/binding/range-inclusive-pattern-precedence.rs deleted file mode 100644 index 858239bb177..00000000000 --- a/src/test/run-pass/binding/range-inclusive-pattern-precedence.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/binding/simple-generic-match.rs b/src/test/run-pass/binding/simple-generic-match.rs deleted file mode 100644 index 50cfe19fef4..00000000000 --- a/src/test/run-pass/binding/simple-generic-match.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/binding/use-uninit-match.rs b/src/test/run-pass/binding/use-uninit-match.rs deleted file mode 100644 index 9250dbf0c43..00000000000 --- a/src/test/run-pass/binding/use-uninit-match.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/binding/use-uninit-match2.rs b/src/test/run-pass/binding/use-uninit-match2.rs deleted file mode 100644 index 9102730629b..00000000000 --- a/src/test/run-pass/binding/use-uninit-match2.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/binding/zero_sized_subslice_match.rs b/src/test/run-pass/binding/zero_sized_subslice_match.rs deleted file mode 100644 index 51e1c024bff..00000000000 --- a/src/test/run-pass/binding/zero_sized_subslice_match.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/binops-issue-22743.rs b/src/test/run-pass/binops-issue-22743.rs deleted file mode 100644 index 393ba0a56cb..00000000000 --- a/src/test/run-pass/binops-issue-22743.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs deleted file mode 100644 index a7abf6087b3..00000000000 --- a/src/test/run-pass/binops.rs +++ /dev/null @@ -1,89 +0,0 @@ -// 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/src/test/run-pass/bitwise.rs b/src/test/run-pass/bitwise.rs deleted file mode 100644 index f79ff3c6efb..00000000000 --- a/src/test/run-pass/bitwise.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/blind-item-local-shadow.rs b/src/test/run-pass/blind-item-local-shadow.rs deleted file mode 100644 index 942aeb6fdf4..00000000000 --- a/src/test/run-pass/blind-item-local-shadow.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/blind-item-mixed-crate-use-item.rs b/src/test/run-pass/blind-item-mixed-crate-use-item.rs deleted file mode 100644 index 36d8ab151e4..00000000000 --- a/src/test/run-pass/blind-item-mixed-crate-use-item.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/blind-item-mixed-use-item.rs b/src/test/run-pass/blind-item-mixed-use-item.rs deleted file mode 100644 index 4a39054967b..00000000000 --- a/src/test/run-pass/blind-item-mixed-use-item.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/block-arg-call-as.rs b/src/test/run-pass/block-arg-call-as.rs deleted file mode 100644 index 87cf3a487bf..00000000000 --- a/src/test/run-pass/block-arg-call-as.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs deleted file mode 100644 index bd1385e5c33..00000000000 --- a/src/test/run-pass/block-arg.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/block-explicit-types.rs b/src/test/run-pass/block-explicit-types.rs deleted file mode 100644 index 860fcc8df21..00000000000 --- a/src/test/run-pass/block-explicit-types.rs +++ /dev/null @@ -1,6 +0,0 @@ -// 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/src/test/run-pass/block-expr-precedence.rs b/src/test/run-pass/block-expr-precedence.rs deleted file mode 100644 index d31eecda9bb..00000000000 --- a/src/test/run-pass/block-expr-precedence.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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; -} diff --git a/src/test/run-pass/block-fn-coerce.rs b/src/test/run-pass/block-fn-coerce.rs deleted file mode 100644 index fc5f51d46b2..00000000000 --- a/src/test/run-pass/block-fn-coerce.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -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/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs deleted file mode 100644 index caf0266cff1..00000000000 --- a/src/test/run-pass/block-iter-1.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs deleted file mode 100644 index e90c1ee815a..00000000000 --- a/src/test/run-pass/block-iter-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/bool-not.rs b/src/test/run-pass/bool-not.rs deleted file mode 100644 index 84713d6818a..00000000000 --- a/src/test/run-pass/bool-not.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -pub fn main() { - if !false { assert!((true)); } else { assert!((false)); } - if !true { assert!((false)); } else { assert!((true)); } -} diff --git a/src/test/run-pass/bool.rs b/src/test/run-pass/bool.rs deleted file mode 100644 index 92f36c8fd25..00000000000 --- a/src/test/run-pass/bool.rs +++ /dev/null @@ -1,72 +0,0 @@ -// 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/src/test/run-pass/borrow-by-val-method-receiver.rs b/src/test/run-pass/borrow-by-val-method-receiver.rs deleted file mode 100644 index 465bef1614d..00000000000 --- a/src/test/run-pass/borrow-by-val-method-receiver.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs b/src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs deleted file mode 100644 index 050d702b625..00000000000 --- a/src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs b/src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs deleted file mode 100644 index 72bf43da95e..00000000000 --- a/src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-binding-mutbl.rs b/src/test/run-pass/borrowck/borrowck-binding-mutbl.rs deleted file mode 100644 index c2d2e02ec15..00000000000 --- a/src/test/run-pass/borrowck/borrowck-binding-mutbl.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs b/src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs deleted file mode 100644 index 15c6e8bf210..00000000000 --- a/src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs deleted file mode 100644 index 2839a9195a0..00000000000 --- a/src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 src/librustc_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/src/test/run-pass/borrowck/borrowck-closures-two-imm.rs b/src/test/run-pass/borrowck/borrowck-closures-two-imm.rs deleted file mode 100644 index ab135194a09..00000000000 --- a/src/test/run-pass/borrowck/borrowck-closures-two-imm.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs b/src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs deleted file mode 100644 index 126323d8d24..00000000000 --- a/src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let x = [22]; - let y = &x[0]; - assert_eq!(*y, 22); -} diff --git a/src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs b/src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs deleted file mode 100644 index 199931d6d1e..00000000000 --- a/src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-lend-args.rs b/src/test/run-pass/borrowck/borrowck-lend-args.rs deleted file mode 100644 index d0ef2dcdd28..00000000000 --- a/src/test/run-pass/borrowck/borrowck-lend-args.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs b/src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs deleted file mode 100644 index 628e49f574c..00000000000 --- a/src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs deleted file mode 100644 index 98e4b881893..00000000000 --- a/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let bar: Box<_> = box 3; - let h = || -> isize { *bar }; - assert_eq!(h(), 3); -} diff --git a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs deleted file mode 100644 index 96d2663500e..00000000000 --- a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck/borrowck-mut-uniq.rs deleted file mode 100644 index 80b3484e0fb..00000000000 --- a/src/test/run-pass/borrowck/borrowck-mut-uniq.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs b/src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs deleted file mode 100644 index d2b0c01545e..00000000000 --- a/src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-pat-enum.rs b/src/test/run-pass/borrowck/borrowck-pat-enum.rs deleted file mode 100644 index 7f9c5544d0b..00000000000 --- a/src/test/run-pass/borrowck/borrowck-pat-enum.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs b/src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs deleted file mode 100644 index 1362fd8ce4c..00000000000 --- a/src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs b/src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs deleted file mode 100644 index c4695c942e1..00000000000 --- a/src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs b/src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs deleted file mode 100644 index e89332ae31a..00000000000 --- a/src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs b/src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs deleted file mode 100644 index 5f4379325a5..00000000000 --- a/src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck/borrowck-trait-lifetime.rs deleted file mode 100644 index 8a6dfe76d60..00000000000 --- a/src/test/run-pass/borrowck/borrowck-trait-lifetime.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs b/src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs deleted file mode 100644 index bdf7cc57a53..00000000000 --- a/src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck/borrowck-univariant-enum.rs deleted file mode 100644 index c78e9475233..00000000000 --- a/src/test/run-pass/borrowck/borrowck-univariant-enum.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs deleted file mode 100644 index adc7dfd541f..00000000000 --- a/src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs b/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs deleted file mode 100644 index fd0e346e2b4..00000000000 --- a/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/borrowck/issue-62007-assign-box.rs b/src/test/run-pass/borrowck/issue-62007-assign-box.rs deleted file mode 100644 index f6fbea821b5..00000000000 --- a/src/test/run-pass/borrowck/issue-62007-assign-box.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/borrowck/issue-62007-assign-field.rs b/src/test/run-pass/borrowck/issue-62007-assign-field.rs deleted file mode 100644 index 5b21c083816..00000000000 --- a/src/test/run-pass/borrowck/issue-62007-assign-field.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/borrowck/two-phase-baseline.rs b/src/test/run-pass/borrowck/two-phase-baseline.rs deleted file mode 100644 index 994dc823dfc..00000000000 --- a/src/test/run-pass/borrowck/two-phase-baseline.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/borrowck/two-phase-bin-ops.rs b/src/test/run-pass/borrowck/two-phase-bin-ops.rs deleted file mode 100644 index 1242ae307d3..00000000000 --- a/src/test/run-pass/borrowck/two-phase-bin-ops.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs b/src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs deleted file mode 100644 index 0b20e1945e6..00000000000 --- a/src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/box-new.rs b/src/test/run-pass/box-new.rs deleted file mode 100644 index be1a40cf779..00000000000 --- a/src/test/run-pass/box-new.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - let _a = Box::new(1); -} diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs deleted file mode 100644 index f53a1736127..00000000000 --- a/src/test/run-pass/bug-7183-generics.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs deleted file mode 100644 index 156ff2ee82f..00000000000 --- a/src/test/run-pass/bug-7295.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/builtin-clone-unwind.rs b/src/test/run-pass/builtin-clone-unwind.rs deleted file mode 100644 index 339bcfa1060..00000000000 --- a/src/test/run-pass/builtin-clone-unwind.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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/src/test/run-pass/builtin-clone.rs b/src/test/run-pass/builtin-clone.rs deleted file mode 100644 index 0874d5bc390..00000000000 --- a/src/test/run-pass/builtin-clone.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs deleted file mode 100644 index 1f997d37122..00000000000 --- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs deleted file mode 100644 index 8416bb3a377..00000000000 --- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs deleted file mode 100644 index e936f921a82..00000000000 --- a/src/test/run-pass/builtin-superkinds-capabilities.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs deleted file mode 100644 index 117014b44ee..00000000000 --- a/src/test/run-pass/builtin-superkinds-in-metadata.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs deleted file mode 100644 index 9b80664b04e..00000000000 --- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-simple.rs b/src/test/run-pass/builtin-superkinds-simple.rs deleted file mode 100644 index 8d247715784..00000000000 --- a/src/test/run-pass/builtin-superkinds-simple.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/builtin-superkinds-typaram.rs b/src/test/run-pass/builtin-superkinds-typaram.rs deleted file mode 100644 index f999dfff786..00000000000 --- a/src/test/run-pass/builtin-superkinds-typaram.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/byte-literals.rs b/src/test/run-pass/byte-literals.rs deleted file mode 100644 index 2649c2eac33..00000000000 --- a/src/test/run-pass/byte-literals.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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/src/test/run-pass/c-stack-as-value.rs b/src/test/run-pass/c-stack-as-value.rs deleted file mode 100644 index 7595b76fb3f..00000000000 --- a/src/test/run-pass/c-stack-as-value.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs deleted file mode 100644 index 388d280b831..00000000000 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/cabi-int-widening.rs b/src/test/run-pass/cabi-int-widening.rs deleted file mode 100644 index 240eaebf3d6..00000000000 --- a/src/test/run-pass/cabi-int-widening.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/can-copy-pod.rs b/src/test/run-pass/can-copy-pod.rs deleted file mode 100644 index e6c57ca3f71..00000000000 --- a/src/test/run-pass/can-copy-pod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs b/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs deleted file mode 100644 index 781d5c14abe..00000000000 --- a/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/cast-does-fallback.rs b/src/test/run-pass/cast-does-fallback.rs deleted file mode 100644 index 770f7a31c76..00000000000 --- a/src/test/run-pass/cast-does-fallback.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/cast-region-to-uint.rs b/src/test/run-pass/cast-region-to-uint.rs deleted file mode 100644 index 33ec2d27610..00000000000 --- a/src/test/run-pass/cast-region-to-uint.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -pub fn main() { - let x: isize = 3; - println!("&x={:x}", (&x as *const isize as usize)); -} diff --git a/src/test/run-pass/cast-rfc0401-vtable-kinds.rs b/src/test/run-pass/cast-rfc0401-vtable-kinds.rs deleted file mode 100644 index 249481467e6..00000000000 --- a/src/test/run-pass/cast-rfc0401-vtable-kinds.rs +++ /dev/null @@ -1,62 +0,0 @@ -// 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/src/test/run-pass/cast-rfc0401.rs b/src/test/run-pass/cast-rfc0401.rs deleted file mode 100644 index 996fa013fed..00000000000 --- a/src/test/run-pass/cast-rfc0401.rs +++ /dev/null @@ -1,173 +0,0 @@ -// 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/src/test/run-pass/cast-to-infer-ty.rs b/src/test/run-pass/cast-to-infer-ty.rs deleted file mode 100644 index 053ebb621a7..00000000000 --- a/src/test/run-pass/cast-to-infer-ty.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/cast.rs b/src/test/run-pass/cast.rs deleted file mode 100644 index 218275c4d99..00000000000 --- a/src/test/run-pass/cast.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/catch-unwind-bang.rs b/src/test/run-pass/catch-unwind-bang.rs deleted file mode 100644 index f181991713b..00000000000 --- a/src/test/run-pass/catch-unwind-bang.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/cell-does-not-clone.rs b/src/test/run-pass/cell-does-not-clone.rs deleted file mode 100644 index 587447b54b7..00000000000 --- a/src/test/run-pass/cell-does-not-clone.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass - -#![allow(dead_code)] - -use std::cell::Cell; - -#[derive(Copy)] -struct Foo { - x: isize -} - -impl Clone for Foo { - fn clone(&self) -> Foo { - // Using Cell in any way should never cause clone() to be - // invoked -- after all, that would permit evil user code to - // abuse `Cell` and trigger crashes. - - panic!(); - } -} - -pub fn main() { - let x = Cell::new(Foo { x: 22 }); - let _y = x.get(); - let _z = x.clone(); -} diff --git a/src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs b/src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs deleted file mode 100644 index 6a619a4e768..00000000000 --- a/src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs +++ /dev/null @@ -1,7 +0,0 @@ -// this used to just ICE on compiling -pub fn foo() { - if cfg!(foo) { - static a: isize = 3; - a - } else { 3 }; -} diff --git a/src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs b/src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs deleted file mode 100644 index 1e0f5d79c0b..00000000000 --- a/src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic -// compile-flags: --cfg foo - -#![cfg_attr(foo, crate_type="lib")] - -pub fn foo() {} diff --git a/src/test/run-pass/cfg/cfg-attr-cfg.rs b/src/test/run-pass/cfg/cfg-attr-cfg.rs deleted file mode 100644 index 61794e0bfa9..00000000000 --- a/src/test/run-pass/cfg/cfg-attr-cfg.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-attr-crate.rs b/src/test/run-pass/cfg/cfg-attr-crate.rs deleted file mode 100644 index 1d70f2f84f2..00000000000 --- a/src/test/run-pass/cfg/cfg-attr-crate.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-family.rs b/src/test/run-pass/cfg/cfg-family.rs deleted file mode 100644 index 9fb7c766921..00000000000 --- a/src/test/run-pass/cfg/cfg-family.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-in-crate-1.rs b/src/test/run-pass/cfg/cfg-in-crate-1.rs deleted file mode 100644 index e84300aa331..00000000000 --- a/src/test/run-pass/cfg/cfg-in-crate-1.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -// compile-flags: --cfg bar -D warnings -#![cfg(bar)] - -fn main() {} diff --git a/src/test/run-pass/cfg/cfg-macros-foo.rs b/src/test/run-pass/cfg/cfg-macros-foo.rs deleted file mode 100644 index 8b112c7961b..00000000000 --- a/src/test/run-pass/cfg/cfg-macros-foo.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-macros-notfoo.rs b/src/test/run-pass/cfg/cfg-macros-notfoo.rs deleted file mode 100644 index 292d97821cd..00000000000 --- a/src/test/run-pass/cfg/cfg-macros-notfoo.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-match-arm.rs b/src/test/run-pass/cfg/cfg-match-arm.rs deleted file mode 100644 index 071008f9eb6..00000000000 --- a/src/test/run-pass/cfg/cfg-match-arm.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-target-family.rs b/src/test/run-pass/cfg/cfg-target-family.rs deleted file mode 100644 index ecf802f7281..00000000000 --- a/src/test/run-pass/cfg/cfg-target-family.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg-target-vendor.rs b/src/test/run-pass/cfg/cfg-target-vendor.rs deleted file mode 100644 index 7824585162e..00000000000 --- a/src/test/run-pass/cfg/cfg-target-vendor.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#[cfg(target_vendor = "unknown")] -pub fn main() { -} - -#[cfg(not(target_vendor = "unknown"))] -pub fn main() { -} diff --git a/src/test/run-pass/cfg/cfg_attr.rs b/src/test/run-pass/cfg/cfg_attr.rs deleted file mode 100644 index c959e68acf9..00000000000 --- a/src/test/run-pass/cfg/cfg_attr.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg_inner_static.rs b/src/test/run-pass/cfg/cfg_inner_static.rs deleted file mode 100644 index 45dbbcc1084..00000000000 --- a/src/test/run-pass/cfg/cfg_inner_static.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/cfg/cfg_stmt_expr.rs b/src/test/run-pass/cfg/cfg_stmt_expr.rs deleted file mode 100644 index e466ad69f72..00000000000 --- a/src/test/run-pass/cfg/cfg_stmt_expr.rs +++ /dev/null @@ -1,92 +0,0 @@ -// 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/src/test/run-pass/cfg/cfgs-on-items.rs b/src/test/run-pass/cfg/cfgs-on-items.rs deleted file mode 100644 index 9f2fc49423e..00000000000 --- a/src/test/run-pass/cfg/cfgs-on-items.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/cfg/conditional-compile-arch.rs b/src/test/run-pass/cfg/conditional-compile-arch.rs deleted file mode 100644 index ea3affee406..00000000000 --- a/src/test/run-pass/cfg/conditional-compile-arch.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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() { } diff --git a/src/test/run-pass/cfg/conditional-compile.rs b/src/test/run-pass/cfg/conditional-compile.rs deleted file mode 100644 index de5bd5f07dd..00000000000 --- a/src/test/run-pass/cfg/conditional-compile.rs +++ /dev/null @@ -1,149 +0,0 @@ -// 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/src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs b/src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs deleted file mode 100644 index 43b266b778f..00000000000 --- a/src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// aux-build:crate-attributes-using-cfg_attr.rs - -extern crate crate_attributes_using_cfg_attr; - -pub fn main() {} diff --git a/src/test/run-pass/chalkify/builtin-copy-clone.rs b/src/test/run-pass/chalkify/builtin-copy-clone.rs deleted file mode 100644 index d403514b553..00000000000 --- a/src/test/run-pass/chalkify/builtin-copy-clone.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/chalkify/inherent_impl.rs b/src/test/run-pass/chalkify/inherent_impl.rs deleted file mode 100644 index 44e120c1eeb..00000000000 --- a/src/test/run-pass/chalkify/inherent_impl.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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_foo(); - s.dummy_bar::(); -} diff --git a/src/test/run-pass/chalkify/projection.rs b/src/test/run-pass/chalkify/projection.rs deleted file mode 100644 index d6a8dd7a4a2..00000000000 --- a/src/test/run-pass/chalkify/projection.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/chalkify/super_trait.rs b/src/test/run-pass/chalkify/super_trait.rs deleted file mode 100644 index eeff9fd9b80..00000000000 --- a/src/test/run-pass/chalkify/super_trait.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/chalkify/trait_implied_bound.rs b/src/test/run-pass/chalkify/trait_implied_bound.rs deleted file mode 100644 index 8a2e1cf5990..00000000000 --- a/src/test/run-pass/chalkify/trait_implied_bound.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/chalkify/type_implied_bound.rs b/src/test/run-pass/chalkify/type_implied_bound.rs deleted file mode 100644 index 8673f5319bd..00000000000 --- a/src/test/run-pass/chalkify/type_implied_bound.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/char.rs b/src/test/run-pass/char.rs deleted file mode 100644 index cfb7a37af01..00000000000 --- a/src/test/run-pass/char.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/char_unicode.rs b/src/test/run-pass/char_unicode.rs deleted file mode 100644 index 93e5300e36f..00000000000 --- a/src/test/run-pass/char_unicode.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - -#![feature(unicode_version)] - -/// Tests access to the internal Unicode Version type and value. -pub fn main() { - check(std::char::UNICODE_VERSION); -} - -pub fn check(unicode_version: std::char::UnicodeVersion) { - assert!(unicode_version.major >= 10); -} diff --git a/src/test/run-pass/check-static-recursion-foreign.rs b/src/test/run-pass/check-static-recursion-foreign.rs deleted file mode 100644 index 8ca0af8e47a..00000000000 --- a/src/test/run-pass/check-static-recursion-foreign.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass - -#![allow(dead_code)] -// 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; - -#[link_name = "check_static_recursion_foreign_helper"] -extern "C" { - #[allow(dead_code)] - static test_static: c_int; -} - -static B: &'static c_int = unsafe { &test_static }; - -pub fn main() {} diff --git a/src/test/run-pass/check_const-feature-gated.rs b/src/test/run-pass/check_const-feature-gated.rs deleted file mode 100644 index f4faab1abc2..00000000000 --- a/src/test/run-pass/check_const-feature-gated.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -const ARR: [usize; 1] = [2]; - -fn main() { - let _ = 5 << ARR[0]; -} diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs deleted file mode 100644 index e3a39a44bb8..00000000000 --- a/src/test/run-pass/child-outlives-parent.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/cleanup-arm-conditional.rs b/src/test/run-pass/cleanup-arm-conditional.rs deleted file mode 100644 index 915842f3e85..00000000000 --- a/src/test/run-pass/cleanup-arm-conditional.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/cleanup-rvalue-during-if-and-while.rs b/src/test/run-pass/cleanup-rvalue-during-if-and-while.rs deleted file mode 100644 index 6fecb4e76da..00000000000 --- a/src/test/run-pass/cleanup-rvalue-during-if-and-while.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/cleanup-rvalue-for-scope.rs b/src/test/run-pass/cleanup-rvalue-for-scope.rs deleted file mode 100644 index b6582c01fba..00000000000 --- a/src/test/run-pass/cleanup-rvalue-for-scope.rs +++ /dev/null @@ -1,63 +0,0 @@ -// 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/src/test/run-pass/cleanup-rvalue-scopes.rs b/src/test/run-pass/cleanup-rvalue-scopes.rs deleted file mode 100644 index f51f13abf79..00000000000 --- a/src/test/run-pass/cleanup-rvalue-scopes.rs +++ /dev/null @@ -1,131 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs deleted file mode 100644 index 62f8b81385a..00000000000 --- a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/cleanup-shortcircuit.rs b/src/test/run-pass/cleanup-shortcircuit.rs deleted file mode 100644 index 19d774079ab..00000000000 --- a/src/test/run-pass/cleanup-shortcircuit.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/clone-with-exterior.rs b/src/test/run-pass/clone-with-exterior.rs deleted file mode 100644 index 1ef29719267..00000000000 --- a/src/test/run-pass/clone-with-exterior.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs deleted file mode 100644 index 40e5f500df4..00000000000 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/cmp-default.rs b/src/test/run-pass/cmp-default.rs deleted file mode 100644 index bb5c39f5cde..00000000000 --- a/src/test/run-pass/cmp-default.rs +++ /dev/null @@ -1,73 +0,0 @@ -// 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/src/test/run-pass/codegen-object-shim.rs b/src/test/run-pass/codegen-object-shim.rs deleted file mode 100644 index 9a85a50ebd9..00000000000 --- a/src/test/run-pass/codegen-object-shim.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -fn main() { - assert_eq!((ToString::to_string as fn(&(dyn ToString+'static)) -> String)(&"foo"), - String::from("foo")); -} diff --git a/src/test/run-pass/coerce/coerce-expect-unsized.rs b/src/test/run-pass/coerce/coerce-expect-unsized.rs deleted file mode 100644 index b44aa6ab377..00000000000 --- a/src/test/run-pass/coerce/coerce-expect-unsized.rs +++ /dev/null @@ -1,43 +0,0 @@ -// run-pass -#![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/src/test/run-pass/coerce/coerce-overloaded-autoderef.rs b/src/test/run-pass/coerce/coerce-overloaded-autoderef.rs deleted file mode 100644 index 3fe18103ef8..00000000000 --- a/src/test/run-pass/coerce/coerce-overloaded-autoderef.rs +++ /dev/null @@ -1,67 +0,0 @@ -// run-pass -#![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/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs b/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs deleted file mode 100644 index f033e1b5d2b..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs deleted file mode 100644 index 64a365229cb..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs b/src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs deleted file mode 100644 index c2aaae1c73e..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs b/src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs deleted file mode 100644 index 9a5652acf87..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs b/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs deleted file mode 100644 index 76cd6793b3c..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs b/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs deleted file mode 100644 index e6e7c3a51aa..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs b/src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs deleted file mode 100644 index 2635754f14d..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs b/src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs deleted file mode 100644 index c03336ea37a..00000000000 --- a/src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-unify-return.rs b/src/test/run-pass/coerce/coerce-unify-return.rs deleted file mode 100644 index 95a7ee8fe0f..00000000000 --- a/src/test/run-pass/coerce/coerce-unify-return.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-unify.rs b/src/test/run-pass/coerce/coerce-unify.rs deleted file mode 100644 index f1818f9bb5a..00000000000 --- a/src/test/run-pass/coerce/coerce-unify.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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/src/test/run-pass/coerce/coerce-unsize-subtype.rs b/src/test/run-pass/coerce/coerce-unsize-subtype.rs deleted file mode 100644 index 45b53300c5b..00000000000 --- a/src/test/run-pass/coerce/coerce-unsize-subtype.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs b/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs deleted file mode 100644 index 9a191bad8b0..00000000000 --- a/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -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/src/test/run-pass/coherence/coherence-bigint-int.rs b/src/test/run-pass/coherence/coherence-bigint-int.rs deleted file mode 100644 index 0c9abdc15e6..00000000000 --- a/src/test/run-pass/coherence/coherence-bigint-int.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// aux-build:coherence_lib.rs -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] - -// 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/src/test/run-pass/coherence/coherence-bigint-vecint.rs b/src/test/run-pass/coherence/coherence-bigint-vecint.rs deleted file mode 100644 index 38e0be0aa9a..00000000000 --- a/src/test/run-pass/coherence/coherence-bigint-vecint.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// aux-build:coherence_lib.rs -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] - -// 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/src/test/run-pass/coherence/coherence-blanket.rs b/src/test/run-pass/coherence/coherence-blanket.rs deleted file mode 100644 index 5d310cc2c6a..00000000000 --- a/src/test/run-pass/coherence/coherence-blanket.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -#![allow(unused_imports)] -// aux-build:coherence_lib.rs -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] - -// 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/src/test/run-pass/coherence/coherence-covered-type-parameter.rs b/src/test/run-pass/coherence/coherence-covered-type-parameter.rs deleted file mode 100644 index 1cf039f0831..00000000000 --- a/src/test/run-pass/coherence/coherence-covered-type-parameter.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -#![allow(dead_code)] -// aux-build:coherence_lib.rs -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] - -// 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/src/test/run-pass/coherence/coherence-impl-in-fn.rs b/src/test/run-pass/coherence/coherence-impl-in-fn.rs deleted file mode 100644 index 09e2c1e5a4e..00000000000 --- a/src/test/run-pass/coherence/coherence-impl-in-fn.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -#![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/src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs b/src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs deleted file mode 100644 index 051cc280b2d..00000000000 --- a/src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -#![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/src/test/run-pass/coherence/coherence-iterator-vec.rs b/src/test/run-pass/coherence/coherence-iterator-vec.rs deleted file mode 100644 index df6e808f7de..00000000000 --- a/src/test/run-pass/coherence/coherence-iterator-vec.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -#![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/src/test/run-pass/coherence/coherence-multidispatch-tuple.rs b/src/test/run-pass/coherence/coherence-multidispatch-tuple.rs deleted file mode 100644 index 6a816664c48..00000000000 --- a/src/test/run-pass/coherence/coherence-multidispatch-tuple.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -#![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/src/test/run-pass/coherence/coherence-rfc447-constrained.rs b/src/test/run-pass/coherence/coherence-rfc447-constrained.rs deleted file mode 100644 index 4da54d386fd..00000000000 --- a/src/test/run-pass/coherence/coherence-rfc447-constrained.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -// 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/src/test/run-pass/coherence/coherence-where-clause.rs b/src/test/run-pass/coherence/coherence-where-clause.rs deleted file mode 100644 index 28397420385..00000000000 --- a/src/test/run-pass/coherence/coherence-where-clause.rs +++ /dev/null @@ -1,41 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] - -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/src/test/run-pass/coherence/coherence_copy_like.rs b/src/test/run-pass/coherence/coherence_copy_like.rs deleted file mode 100644 index 653f76264c1..00000000000 --- a/src/test/run-pass/coherence/coherence_copy_like.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -// revisions: old re - -#![cfg_attr(re, feature(re_rebalance_coherence))] -#![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/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs deleted file mode 100644 index 4168b7a6146..00000000000 --- a/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// aux-build:re_rebalance_coherence_lib.rs - -#![allow(dead_code)] -#![feature(re_rebalance_coherence)] -// 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 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/src/test/run-pass/collections-const-new.rs b/src/test/run-pass/collections-const-new.rs deleted file mode 100644 index e01b0dfa14d..00000000000 --- a/src/test/run-pass/collections-const-new.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![allow(dead_code)] -// Test several functions can be used for constants -// 1. Vec::new() -// 2. String::new() - -#![feature(const_vec_new)] -#![feature(const_string_new)] - -const MY_VEC: Vec = Vec::new(); - -const MY_STRING: String = String::new(); - -pub fn main() {} diff --git a/src/test/run-pass/command-exec.rs b/src/test/run-pass/command-exec.rs deleted file mode 100644 index 568be67abe3..00000000000 --- a/src/test/run-pass/command-exec.rs +++ /dev/null @@ -1,104 +0,0 @@ -// 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/src/test/run-pass/command-pre-exec.rs b/src/test/run-pass/command-pre-exec.rs deleted file mode 100644 index c0fc554183a..00000000000 --- a/src/test/run-pass/command-pre-exec.rs +++ /dev/null @@ -1,118 +0,0 @@ -// 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/src/test/run-pass/command-uid-gid.rs b/src/test/run-pass/command-uid-gid.rs deleted file mode 100644 index f867106c35d..00000000000 --- a/src/test/run-pass/command-uid-gid.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/complex.rs b/src/test/run-pass/complex.rs deleted file mode 100644 index 9b11ca67e47..00000000000 --- a/src/test/run-pass/complex.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/consts/assoc-const.rs b/src/test/run-pass/consts/assoc-const.rs deleted file mode 100644 index b70479d255b..00000000000 --- a/src/test/run-pass/consts/assoc-const.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688eb..00000000000 --- a/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![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/src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs b/src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs deleted file mode 100644 index 7c57a1c6678..00000000000 --- a/src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn foo(x: &usize) -> usize { - *x -} diff --git a/src/test/run-pass/consts/auxiliary/cci_const.rs b/src/test/run-pass/consts/auxiliary/cci_const.rs deleted file mode 100644 index af6a5ad8ed3..00000000000 --- a/src/test/run-pass/consts/auxiliary/cci_const.rs +++ /dev/null @@ -1,6 +0,0 @@ -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/src/test/run-pass/consts/auxiliary/cci_const_block.rs b/src/test/run-pass/consts/auxiliary/cci_const_block.rs deleted file mode 100644 index ad618aab830..00000000000 --- a/src/test/run-pass/consts/auxiliary/cci_const_block.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub static BLOCK_FN_DEF: fn(usize) -> usize = { - fn foo(a: usize) -> usize { - a + 10 - } - foo -}; diff --git a/src/test/run-pass/consts/bswap-const.rs b/src/test/run-pass/consts/bswap-const.rs deleted file mode 100644 index 3145c21acc9..00000000000 --- a/src/test/run-pass/consts/bswap-const.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/chained-constants-stackoverflow.rs b/src/test/run-pass/consts/chained-constants-stackoverflow.rs deleted file mode 100644 index a171567c5d2..00000000000 --- a/src/test/run-pass/consts/chained-constants-stackoverflow.rs +++ /dev/null @@ -1,356 +0,0 @@ -// 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/src/test/run-pass/consts/const-adt-align-mismatch.rs b/src/test/run-pass/consts/const-adt-align-mismatch.rs deleted file mode 100644 index bd51bc9f215..00000000000 --- a/src/test/run-pass/consts/const-adt-align-mismatch.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/consts/const-autoderef.rs b/src/test/run-pass/consts/const-autoderef.rs deleted file mode 100644 index 1c836318d32..00000000000 --- a/src/test/run-pass/consts/const-autoderef.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/consts/const-big-enum.rs b/src/test/run-pass/consts/const-big-enum.rs deleted file mode 100644 index 2f21e8a6ddd..00000000000 --- a/src/test/run-pass/consts/const-big-enum.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/consts/const-binops.rs b/src/test/run-pass/consts/const-binops.rs deleted file mode 100644 index d038dfeb419..00000000000 --- a/src/test/run-pass/consts/const-binops.rs +++ /dev/null @@ -1,126 +0,0 @@ -// 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/src/test/run-pass/consts/const-bitshift-rhs-inference.rs b/src/test/run-pass/consts/const-bitshift-rhs-inference.rs deleted file mode 100644 index cf21c296cf3..00000000000 --- a/src/test/run-pass/consts/const-bitshift-rhs-inference.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/consts/const-block-cross-crate-fn.rs b/src/test/run-pass/consts/const-block-cross-crate-fn.rs deleted file mode 100644 index 0ac3830d230..00000000000 --- a/src/test/run-pass/consts/const-block-cross-crate-fn.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/consts/const-block-item-macro-codegen.rs b/src/test/run-pass/consts/const-block-item-macro-codegen.rs deleted file mode 100644 index 7ad883686ae..00000000000 --- a/src/test/run-pass/consts/const-block-item-macro-codegen.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/consts/const-block-item.rs b/src/test/run-pass/consts/const-block-item.rs deleted file mode 100644 index cf0d4441d4a..00000000000 --- a/src/test/run-pass/consts/const-block-item.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/consts/const-block-non-item-statement-3.rs b/src/test/run-pass/consts/const-block-non-item-statement-3.rs deleted file mode 100644 index 10a4c31f24e..00000000000 --- a/src/test/run-pass/consts/const-block-non-item-statement-3.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(dead_code)] - -type Array = [u32; { let x = 2; 5 }]; - -pub fn main() { - let _: Array = [0; 5]; -} diff --git a/src/test/run-pass/consts/const-block.rs b/src/test/run-pass/consts/const-block.rs deleted file mode 100644 index 7172a34c8cf..00000000000 --- a/src/test/run-pass/consts/const-block.rs +++ /dev/null @@ -1,45 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/consts/const-bound.rs b/src/test/run-pass/consts/const-bound.rs deleted file mode 100644 index 735056a0ab0..00000000000 --- a/src/test/run-pass/consts/const-bound.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/consts/const-byte-str-cast.rs b/src/test/run-pass/consts/const-byte-str-cast.rs deleted file mode 100644 index 65d626c297f..00000000000 --- a/src/test/run-pass/consts/const-byte-str-cast.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/consts/const-cast-ptr-int.rs b/src/test/run-pass/consts/const-cast-ptr-int.rs deleted file mode 100644 index 987d9616e91..00000000000 --- a/src/test/run-pass/consts/const-cast-ptr-int.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-cast.rs b/src/test/run-pass/consts/const-cast.rs deleted file mode 100644 index 0d8609e334a..00000000000 --- a/src/test/run-pass/consts/const-cast.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-const.rs b/src/test/run-pass/consts/const-const.rs deleted file mode 100644 index 85e4a72e86d..00000000000 --- a/src/test/run-pass/consts/const-const.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/consts/const-contents.rs b/src/test/run-pass/consts/const-contents.rs deleted file mode 100644 index 7ba3d435650..00000000000 --- a/src/test/run-pass/consts/const-contents.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/consts/const-cross-crate-const.rs b/src/test/run-pass/consts/const-cross-crate-const.rs deleted file mode 100644 index 92020417ff5..00000000000 --- a/src/test/run-pass/consts/const-cross-crate-const.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-cross-crate-extern.rs b/src/test/run-pass/consts/const-cross-crate-extern.rs deleted file mode 100644 index 3c61afd5bec..00000000000 --- a/src/test/run-pass/consts/const-cross-crate-extern.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/consts/const-deref.rs b/src/test/run-pass/consts/const-deref.rs deleted file mode 100644 index 6060d8e510e..00000000000 --- a/src/test/run-pass/consts/const-deref.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -const C: &'static isize = &1000; -static D: isize = *C; - -pub fn main() { - assert_eq!(D, 1000); -} diff --git a/src/test/run-pass/consts/const-endianess.rs b/src/test/run-pass/consts/const-endianess.rs deleted file mode 100644 index 936f31954d3..00000000000 --- a/src/test/run-pass/consts/const-endianess.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-byref-self.rs b/src/test/run-pass/consts/const-enum-byref-self.rs deleted file mode 100644 index b7e14bfb765..00000000000 --- a/src/test/run-pass/consts/const-enum-byref-self.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-byref.rs b/src/test/run-pass/consts/const-enum-byref.rs deleted file mode 100644 index badf5294654..00000000000 --- a/src/test/run-pass/consts/const-enum-byref.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-cast.rs b/src/test/run-pass/consts/const-enum-cast.rs deleted file mode 100644 index a3255c2f601..00000000000 --- a/src/test/run-pass/consts/const-enum-cast.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-ptr.rs b/src/test/run-pass/consts/const-enum-ptr.rs deleted file mode 100644 index 84f4eb8406d..00000000000 --- a/src/test/run-pass/consts/const-enum-ptr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-struct.rs b/src/test/run-pass/consts/const-enum-struct.rs deleted file mode 100644 index ee88c936188..00000000000 --- a/src/test/run-pass/consts/const-enum-struct.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-struct2.rs b/src/test/run-pass/consts/const-enum-struct2.rs deleted file mode 100644 index 6dfe63d5d00..00000000000 --- a/src/test/run-pass/consts/const-enum-struct2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-structlike.rs b/src/test/run-pass/consts/const-enum-structlike.rs deleted file mode 100644 index 0ea79aebce6..00000000000 --- a/src/test/run-pass/consts/const-enum-structlike.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-tuple.rs b/src/test/run-pass/consts/const-enum-tuple.rs deleted file mode 100644 index e0363166b02..00000000000 --- a/src/test/run-pass/consts/const-enum-tuple.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-tuple2.rs b/src/test/run-pass/consts/const-enum-tuple2.rs deleted file mode 100644 index ef378b5995d..00000000000 --- a/src/test/run-pass/consts/const-enum-tuple2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-tuplestruct.rs b/src/test/run-pass/consts/const-enum-tuplestruct.rs deleted file mode 100644 index f93945c6a68..00000000000 --- a/src/test/run-pass/consts/const-enum-tuplestruct.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-tuplestruct2.rs b/src/test/run-pass/consts/const-enum-tuplestruct2.rs deleted file mode 100644 index b8aa9a3152f..00000000000 --- a/src/test/run-pass/consts/const-enum-tuplestruct2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-vec-index.rs b/src/test/run-pass/consts/const-enum-vec-index.rs deleted file mode 100644 index 3f155340ab5..00000000000 --- a/src/test/run-pass/consts/const-enum-vec-index.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-vec-ptr.rs b/src/test/run-pass/consts/const-enum-vec-ptr.rs deleted file mode 100644 index 43ffe6570dc..00000000000 --- a/src/test/run-pass/consts/const-enum-vec-ptr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/const-enum-vector.rs b/src/test/run-pass/consts/const-enum-vector.rs deleted file mode 100644 index ee3739f9723..00000000000 --- a/src/test/run-pass/consts/const-enum-vector.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs b/src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs deleted file mode 100644 index a9960b4552b..00000000000 --- a/src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-expr-in-vec-repeat.rs b/src/test/run-pass/consts/const-expr-in-vec-repeat.rs deleted file mode 100644 index 4eaef25059b..00000000000 --- a/src/test/run-pass/consts/const-expr-in-vec-repeat.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/consts/const-extern-function.rs b/src/test/run-pass/consts/const-extern-function.rs deleted file mode 100644 index cfcf99b867a..00000000000 --- a/src/test/run-pass/consts/const-extern-function.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-fields-and-indexing.rs b/src/test/run-pass/consts/const-fields-and-indexing.rs deleted file mode 100644 index bb13bebf4e2..00000000000 --- a/src/test/run-pass/consts/const-fields-and-indexing.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-const-eval.rs b/src/test/run-pass/consts/const-fn-const-eval.rs deleted file mode 100644 index d4da990812e..00000000000 --- a/src/test/run-pass/consts/const-fn-const-eval.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-feature-flags.rs b/src/test/run-pass/consts/const-fn-feature-flags.rs deleted file mode 100644 index 30e7e102b86..00000000000 --- a/src/test/run-pass/consts/const-fn-feature-flags.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-method.rs b/src/test/run-pass/consts/const-fn-method.rs deleted file mode 100644 index 002646db92a..00000000000 --- a/src/test/run-pass/consts/const-fn-method.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-nested.rs b/src/test/run-pass/consts/const-fn-nested.rs deleted file mode 100644 index ef5598bf9e7..00000000000 --- a/src/test/run-pass/consts/const-fn-nested.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-stability-calls.rs b/src/test/run-pass/consts/const-fn-stability-calls.rs deleted file mode 100644 index 13867904895..00000000000 --- a/src/test/run-pass/consts/const-fn-stability-calls.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn-type-name.rs b/src/test/run-pass/consts/const-fn-type-name.rs deleted file mode 100644 index 2bb1aeecf37..00000000000 --- a/src/test/run-pass/consts/const-fn-type-name.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass - -#![feature(core_intrinsics)] -#![feature(const_fn)] -#![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/src/test/run-pass/consts/const-fn-val.rs b/src/test/run-pass/consts/const-fn-val.rs deleted file mode 100644 index e5bf4757e3a..00000000000 --- a/src/test/run-pass/consts/const-fn-val.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/const-fn.rs b/src/test/run-pass/consts/const-fn.rs deleted file mode 100644 index 7b924aa46aa..00000000000 --- a/src/test/run-pass/consts/const-fn.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/consts/const-index-feature-gate.rs b/src/test/run-pass/consts/const-index-feature-gate.rs deleted file mode 100644 index 3537a1790cc..00000000000 --- a/src/test/run-pass/consts/const-index-feature-gate.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![allow(dead_code)] -const ARR: [usize; 1] = [2]; -const ARR2: [i32; ARR[0]] = [5, 6]; - -fn main() { -} diff --git a/src/test/run-pass/consts/const-int-saturating-arith.rs b/src/test/run-pass/consts/const-int-saturating-arith.rs deleted file mode 100644 index 394d6c17f5a..00000000000 --- a/src/test/run-pass/consts/const-int-saturating-arith.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// ignore-emscripten no i128 support -#![feature(const_saturating_int_methods)] - -const INT_U32_NO: u32 = (42 as u32).saturating_add(2); -const INT_U32: u32 = u32::max_value().saturating_add(1); -const INT_U128: u128 = u128::max_value().saturating_add(1); -const INT_I128: i128 = i128::max_value().saturating_add(1); -const INT_I128_NEG: i128 = i128::min_value().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_value().saturating_sub(1); -const INT_I32_POS_SUB: i32 = i32::max_value().saturating_sub(-1); -const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1); -const INT_I128_NEG_SUB: i128 = i128::min_value().saturating_sub(1); -const INT_I128_POS_SUB: i128 = i128::max_value().saturating_sub(-1); - -fn main() { - assert_eq!(INT_U32_NO, 44); - assert_eq!(INT_U32, u32::max_value()); - assert_eq!(INT_U128, u128::max_value()); - assert_eq!(INT_I128, i128::max_value()); - assert_eq!(INT_I128_NEG, i128::min_value()); - - 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_value()); - assert_eq!(INT_I32_POS_SUB, i32::max_value()); - assert_eq!(INT_U128_SUB, 0); - assert_eq!(INT_I128_NEG_SUB, i128::min_value()); - assert_eq!(INT_I128_POS_SUB, i128::max_value()); -} diff --git a/src/test/run-pass/consts/const-meth-pattern.rs b/src/test/run-pass/consts/const-meth-pattern.rs deleted file mode 100644 index 1544d760a13..00000000000 --- a/src/test/run-pass/consts/const-meth-pattern.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/consts/const-needs_drop.rs b/src/test/run-pass/consts/const-needs_drop.rs deleted file mode 100644 index 58e80116442..00000000000 --- a/src/test/run-pass/consts/const-needs_drop.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/consts/const-negation.rs b/src/test/run-pass/consts/const-negation.rs deleted file mode 100644 index 1c8e27ae617..00000000000 --- a/src/test/run-pass/consts/const-negation.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/consts/const-negative.rs b/src/test/run-pass/consts/const-negative.rs deleted file mode 100644 index 1cb56093628..00000000000 --- a/src/test/run-pass/consts/const-negative.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/consts/const-nullary-enum.rs b/src/test/run-pass/consts/const-nullary-enum.rs deleted file mode 100644 index b6574dce6ca..00000000000 --- a/src/test/run-pass/consts/const-nullary-enum.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/consts/const-nullary-univariant-enum.rs b/src/test/run-pass/consts/const-nullary-univariant-enum.rs deleted file mode 100644 index 51349ad3195..00000000000 --- a/src/test/run-pass/consts/const-nullary-univariant-enum.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/const-pattern-variant.rs b/src/test/run-pass/consts/const-pattern-variant.rs deleted file mode 100644 index 80f749ed72d..00000000000 --- a/src/test/run-pass/consts/const-pattern-variant.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/consts/const-rec-and-tup.rs b/src/test/run-pass/consts/const-rec-and-tup.rs deleted file mode 100644 index 0bddaf75de8..00000000000 --- a/src/test/run-pass/consts/const-rec-and-tup.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/consts/const-region-ptrs-noncopy.rs b/src/test/run-pass/consts/const-region-ptrs-noncopy.rs deleted file mode 100644 index 10b9ce896a6..00000000000 --- a/src/test/run-pass/consts/const-region-ptrs-noncopy.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/const-region-ptrs.rs b/src/test/run-pass/consts/const-region-ptrs.rs deleted file mode 100644 index 9b94a2b1121..00000000000 --- a/src/test/run-pass/consts/const-region-ptrs.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/consts/const-repeated-values.rs b/src/test/run-pass/consts/const-repeated-values.rs deleted file mode 100644 index 27efb5ba2a2..00000000000 --- a/src/test/run-pass/consts/const-repeated-values.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -const FOO: isize = 42; - -enum Bar { - Boo = *[&FOO; 4][3], -} - -fn main() { - assert_eq!(Bar::Boo as isize, 42); -} diff --git a/src/test/run-pass/consts/const-size_of-align_of.rs b/src/test/run-pass/consts/const-size_of-align_of.rs deleted file mode 100644 index 0c63dc84a37..00000000000 --- a/src/test/run-pass/consts/const-size_of-align_of.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/consts/const-str-ptr.rs b/src/test/run-pass/consts/const-str-ptr.rs deleted file mode 100644 index 56fd9d9f55f..00000000000 --- a/src/test/run-pass/consts/const-str-ptr.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/consts/const-struct-offsets.rs b/src/test/run-pass/consts/const-struct-offsets.rs deleted file mode 100644 index 26a00832079..00000000000 --- a/src/test/run-pass/consts/const-struct-offsets.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/consts/const-struct.rs b/src/test/run-pass/consts/const-struct.rs deleted file mode 100644 index db397a891d6..00000000000 --- a/src/test/run-pass/consts/const-struct.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/consts/const-trait-to-trait.rs b/src/test/run-pass/consts/const-trait-to-trait.rs deleted file mode 100644 index 12a2999d79d..00000000000 --- a/src/test/run-pass/consts/const-trait-to-trait.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/consts/const-tuple-struct.rs b/src/test/run-pass/consts/const-tuple-struct.rs deleted file mode 100644 index 0144afaaceb..00000000000 --- a/src/test/run-pass/consts/const-tuple-struct.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/consts/const-unit-struct.rs b/src/test/run-pass/consts/const-unit-struct.rs deleted file mode 100644 index 1c9e0e8d3c9..00000000000 --- a/src/test/run-pass/consts/const-unit-struct.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -struct Foo; - -static X: Foo = Foo; - -pub fn main() { - match X { - Foo => {} - } -} diff --git a/src/test/run-pass/consts/const-unsafe-fn.rs b/src/test/run-pass/consts/const-unsafe-fn.rs deleted file mode 100644 index 72ce73f745f..00000000000 --- a/src/test/run-pass/consts/const-unsafe-fn.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/consts/const-vec-of-fns.rs b/src/test/run-pass/consts/const-vec-of-fns.rs deleted file mode 100644 index 6d90b066b74..00000000000 --- a/src/test/run-pass/consts/const-vec-of-fns.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/consts/const-vec-syntax.rs b/src/test/run-pass/consts/const-vec-syntax.rs deleted file mode 100644 index 61246e44eba..00000000000 --- a/src/test/run-pass/consts/const-vec-syntax.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn f(_: &[isize]) {} - -pub fn main() { - let v = [ 1, 2, 3 ]; - f(&v); -} diff --git a/src/test/run-pass/consts/const-vecs-and-slices.rs b/src/test/run-pass/consts/const-vecs-and-slices.rs deleted file mode 100644 index 1cdc33b7a34..00000000000 --- a/src/test/run-pass/consts/const-vecs-and-slices.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/consts/const.rs b/src/test/run-pass/consts/const.rs deleted file mode 100644 index 71fbadfa828..00000000000 --- a/src/test/run-pass/consts/const.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -#![allow(non_upper_case_globals)] - -static i: isize = 10; - -pub fn main() { println!("{}", i); } diff --git a/src/test/run-pass/consts/consts-in-patterns.rs b/src/test/run-pass/consts/consts-in-patterns.rs deleted file mode 100644 index ac6c5a51506..00000000000 --- a/src/test/run-pass/consts/consts-in-patterns.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass - -const FOO: isize = 10; -const BAR: isize = 3; - -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); -} diff --git a/src/test/run-pass/consts/deref_in_pattern.rs b/src/test/run-pass/consts/deref_in_pattern.rs deleted file mode 100644 index cc47b5b49c0..00000000000 --- a/src/test/run-pass/consts/deref_in_pattern.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/ice-48279.rs b/src/test/run-pass/consts/ice-48279.rs deleted file mode 100644 index d1d90df240c..00000000000 --- a/src/test/run-pass/consts/ice-48279.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/consts/issue-37550.rs b/src/test/run-pass/consts/issue-37550.rs deleted file mode 100644 index 04865830df2..00000000000 --- a/src/test/run-pass/consts/issue-37550.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] - -#![feature(const_fn)] - -const fn x() { - let t = true; - let x = || t; -} - -fn main() {} diff --git a/src/test/run-pass/consts/issue-broken-mir.rs b/src/test/run-pass/consts/issue-broken-mir.rs deleted file mode 100644 index 36f0ff92104..00000000000 --- a/src/test/run-pass/consts/issue-broken-mir.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -// https://github.com/rust-lang/rust/issues/27918 - -fn main() { - match b" " { - b"1234" => {}, - _ => {}, - } -} diff --git a/src/test/run-pass/consts/locals-in-const-fn.rs b/src/test/run-pass/consts/locals-in-const-fn.rs deleted file mode 100644 index 95d50171a84..00000000000 --- a/src/test/run-pass/consts/locals-in-const-fn.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/consts/match-const-fn-structs.rs b/src/test/run-pass/consts/match-const-fn-structs.rs deleted file mode 100644 index 5a68048c477..00000000000 --- a/src/test/run-pass/consts/match-const-fn-structs.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/consts/mozjs-error.rs b/src/test/run-pass/consts/mozjs-error.rs deleted file mode 100644 index 7edcadbf2cb..00000000000 --- a/src/test/run-pass/consts/mozjs-error.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/consts/non-scalar-cast.rs b/src/test/run-pass/consts/non-scalar-cast.rs deleted file mode 100644 index 671366c90ec..00000000000 --- a/src/test/run-pass/consts/non-scalar-cast.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/consts/promotion.rs b/src/test/run-pass/consts/promotion.rs deleted file mode 100644 index 3c5401e4212..00000000000 --- a/src/test/run-pass/consts/promotion.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-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/src/test/run-pass/consts/references.rs b/src/test/run-pass/consts/references.rs deleted file mode 100644 index d0af47a8ea8..00000000000 --- a/src/test/run-pass/consts/references.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/consts/repeat_match.rs b/src/test/run-pass/consts/repeat_match.rs deleted file mode 100644 index 20983184a47..00000000000 --- a/src/test/run-pass/consts/repeat_match.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/consts/return-in-const-fn.rs b/src/test/run-pass/consts/return-in-const-fn.rs deleted file mode 100644 index 077a33c081b..00000000000 --- a/src/test/run-pass/consts/return-in-const-fn.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/consts/signed_enum_discr.rs b/src/test/run-pass/consts/signed_enum_discr.rs deleted file mode 100644 index 2e4395ccf22..00000000000 --- a/src/test/run-pass/consts/signed_enum_discr.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/consts/transmute-const.rs b/src/test/run-pass/consts/transmute-const.rs deleted file mode 100644 index e24f89cdffd..00000000000 --- a/src/test/run-pass/consts/transmute-const.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -#![feature(const_transmute)] - -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/src/test/run-pass/consts/tuple-struct-constructors.rs b/src/test/run-pass/consts/tuple-struct-constructors.rs deleted file mode 100644 index 1655f0eb850..00000000000 --- a/src/test/run-pass/consts/tuple-struct-constructors.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs deleted file mode 100644 index 225b2ca8f4d..00000000000 --- a/src/test/run-pass/core-run-destroy.rs +++ /dev/null @@ -1,87 +0,0 @@ -// 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 - -// 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/src/test/run-pass/crate-leading-sep.rs b/src/test/run-pass/crate-leading-sep.rs deleted file mode 100644 index ca5905fab41..00000000000 --- a/src/test/run-pass/crate-leading-sep.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - use ::std::mem; - mem::drop(2_usize); -} diff --git a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs b/src/test/run-pass/crate-method-reexport-grrrrrrr.rs deleted file mode 100644 index eefcf7738ad..00000000000 --- a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/crate-name-attr-used.rs b/src/test/run-pass/crate-name-attr-used.rs deleted file mode 100644 index ad53a53143e..00000000000 --- a/src/test/run-pass/crate-name-attr-used.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs deleted file mode 100644 index 77168be5374..00000000000 --- a/src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688eb..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs b/src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs deleted file mode 100644 index dceec7e3ec1..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct Foo { - pub x: isize -} - -impl Foo { - pub fn new() -> Foo { - Foo { x: 3 } - } -} diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs b/src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs deleted file mode 100644 index 7c57a1c6678..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn foo(x: &usize) -> usize { - *x -} diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs b/src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs deleted file mode 100644 index 4cd001ecc9e..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/src/test/run-pass/cross-crate/auxiliary/cci_const.rs b/src/test/run-pass/cross-crate/auxiliary/cci_const.rs deleted file mode 100644 index af6a5ad8ed3..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_const.rs +++ /dev/null @@ -1,6 +0,0 @@ -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/src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs b/src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs deleted file mode 100644 index 0db0037b203..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs b/src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs deleted file mode 100644 index 60c36bc7d05..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs b/src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs deleted file mode 100644 index 379ed076611..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs b/src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs deleted file mode 100644 index 177dba2178f..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs b/src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs deleted file mode 100644 index 7e7e3b86024..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![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/src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs b/src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs deleted file mode 100644 index 9d1e0742e3c..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type="lib"] - -pub struct Au(pub isize); diff --git a/src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs b/src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs deleted file mode 100644 index 49cb76921ad..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs +++ /dev/null @@ -1 +0,0 @@ -pub static ARRAY: [u8; 1] = [1]; diff --git a/src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs b/src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs deleted file mode 100644 index cc961625f32..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs +++ /dev/null @@ -1,43 +0,0 @@ -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/src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs deleted file mode 100644 index 7c1175f7a88..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait FromBuf<'a> { - fn from_buf(_: &'a [u8]) -> Self; -} diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs deleted file mode 100644 index e79e334b53f..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub fn foo() -> isize { - static a: isize = 3; - a -} - -pub fn bar() -> isize { - foo::() -} diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs deleted file mode 100644 index d8a55dd34bc..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(associated_type_defaults)] - -pub trait Foo { - type Out: Default + ToString = T; -} - -impl Foo for () { -} - -impl Foo for () { - type Out = bool; -} diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs deleted file mode 100644 index 2ab23b4d7e4..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs +++ /dev/null @@ -1,16 +0,0 @@ -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/src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs deleted file mode 100644 index e18d34799ef..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs b/src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs deleted file mode 100644 index 69ed498e7e1..00000000000 --- a/src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![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/src/test/run-pass/cross-crate/cci_borrow.rs b/src/test/run-pass/cross-crate/cci_borrow.rs deleted file mode 100644 index 605a166ffa3..00000000000 --- a/src/test/run-pass/cross-crate/cci_borrow.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cci_capture_clause.rs b/src/test/run-pass/cross-crate/cci_capture_clause.rs deleted file mode 100644 index ea699b5f5ac..00000000000 --- a/src/test/run-pass/cross-crate/cci_capture_clause.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cci_impl_exe.rs b/src/test/run-pass/cross-crate/cci_impl_exe.rs deleted file mode 100644 index b11fb23ebc8..00000000000 --- a/src/test/run-pass/cross-crate/cci_impl_exe.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cci_iter_exe.rs b/src/test/run-pass/cross-crate/cci_iter_exe.rs deleted file mode 100644 index 8b58d90fe4e..00000000000 --- a/src/test/run-pass/cross-crate/cci_iter_exe.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cci_nested_exe.rs b/src/test/run-pass/cross-crate/cci_nested_exe.rs deleted file mode 100644 index 1c001a2a372..00000000000 --- a/src/test/run-pass/cross-crate/cci_nested_exe.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cci_no_inline_exe.rs b/src/test/run-pass/cross-crate/cci_no_inline_exe.rs deleted file mode 100644 index ffc701678d3..00000000000 --- a/src/test/run-pass/cross-crate/cci_no_inline_exe.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cross-crate-const-pat.rs b/src/test/run-pass/cross-crate/cross-crate-const-pat.rs deleted file mode 100644 index e8fa8485ab2..00000000000 --- a/src/test/run-pass/cross-crate/cross-crate-const-pat.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs b/src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs deleted file mode 100644 index eabffc16170..00000000000 --- a/src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs b/src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs deleted file mode 100644 index 3881e335220..00000000000 --- a/src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs b/src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs deleted file mode 100644 index 8c70a1ce477..00000000000 --- a/src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/cross-crate/static-array-across-crate.rs b/src/test/run-pass/cross-crate/static-array-across-crate.rs deleted file mode 100644 index 0b84e0e6a3f..00000000000 --- a/src/test/run-pass/cross-crate/static-array-across-crate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate-address-insignificant.rs b/src/test/run-pass/cross-crate/xcrate-address-insignificant.rs deleted file mode 100644 index 33c70650603..00000000000 --- a/src/test/run-pass/cross-crate/xcrate-address-insignificant.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs b/src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs deleted file mode 100644 index 0f3e077d1de..00000000000 --- a/src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate-static-addresses.rs b/src/test/run-pass/cross-crate/xcrate-static-addresses.rs deleted file mode 100644 index 3c33976568e..00000000000 --- a/src/test/run-pass/cross-crate/xcrate-static-addresses.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs b/src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs deleted file mode 100644 index 1fd7eb878d9..00000000000 --- a/src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate-unit-struct.rs b/src/test/run-pass/cross-crate/xcrate-unit-struct.rs deleted file mode 100644 index 7aa3eb0d6c4..00000000000 --- a/src/test/run-pass/cross-crate/xcrate-unit-struct.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs b/src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs deleted file mode 100644 index 4593fec5196..00000000000 --- a/src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/crt-static-off-works.rs b/src/test/run-pass/crt-static-off-works.rs deleted file mode 100644 index 911467ee54e..00000000000 --- a/src/test/run-pass/crt-static-off-works.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/crt-static-on-works.rs b/src/test/run-pass/crt-static-on-works.rs deleted file mode 100644 index 21407b1b911..00000000000 --- a/src/test/run-pass/crt-static-on-works.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -#![allow(stable_features)] -// compile-flags:-C target-feature=+crt-static -Z unstable-options - -#![feature(cfg_target_feature)] - -#[cfg(target_feature = "crt-static")] -fn main() {} diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/run-pass/cycle-generic-bound.rs deleted file mode 100644 index 9241f3789d7..00000000000 --- a/src/test/run-pass/cycle-generic-bound.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/dead-code-alias-in-pat.rs b/src/test/run-pass/dead-code-alias-in-pat.rs deleted file mode 100644 index 69d455f3b60..00000000000 --- a/src/test/run-pass/dead-code-alias-in-pat.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/dead-code-leading-underscore.rs b/src/test/run-pass/dead-code-leading-underscore.rs deleted file mode 100644 index 1b6e03ab887..00000000000 --- a/src/test/run-pass/dead-code-leading-underscore.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/debuginfo-lto.rs b/src/test/run-pass/debuginfo-lto.rs deleted file mode 100644 index e4beee9e737..00000000000 --- a/src/test/run-pass/debuginfo-lto.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 - -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/src/test/run-pass/deep.rs b/src/test/run-pass/deep.rs deleted file mode 100644 index 2bb109c0e3f..00000000000 --- a/src/test/run-pass/deep.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/default-alloc-error-hook.rs b/src/test/run-pass/default-alloc-error-hook.rs deleted file mode 100644 index 40f61c2b7d5..00000000000 --- a/src/test/run-pass/default-alloc-error-hook.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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"); -} diff --git a/src/test/run-pass/default-associated-types.rs b/src/test/run-pass/default-associated-types.rs deleted file mode 100644 index aae70bffa38..00000000000 --- a/src/test/run-pass/default-associated-types.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass - -#![feature(associated_type_defaults)] - -trait Foo { - type Out: Default + ToString = T; -} - -impl Foo for () { -} - -impl Foo for () { - type Out = bool; -} - -fn main() { - assert_eq!( - <() as Foo>::Out::default().to_string(), - "0"); - assert_eq!( - <() as Foo>::Out::default().to_string(), - "false"); -} diff --git a/src/test/run-pass/default-method-parsing.rs b/src/test/run-pass/default-method-parsing.rs deleted file mode 100644 index 9ffb8d94a59..00000000000 --- a/src/test/run-pass/default-method-parsing.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -trait Foo { - fn m(&self, _:isize) { } -} - -pub fn main() { } diff --git a/src/test/run-pass/default-method-simple.rs b/src/test/run-pass/default-method-simple.rs deleted file mode 100644 index 6f7ae6a3e0b..00000000000 --- a/src/test/run-pass/default-method-simple.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/defaults-well-formedness.rs b/src/test/run-pass/defaults-well-formedness.rs deleted file mode 100644 index 3275890616b..00000000000 --- a/src/test/run-pass/defaults-well-formedness.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/deprecation-in-force-unstable.rs b/src/test/run-pass/deprecation-in-force-unstable.rs deleted file mode 100644 index 4df9b802d45..00000000000 --- a/src/test/run-pass/deprecation-in-force-unstable.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -// compile-flags:-Zforce-unstable-if-unmarked - -#[deprecated] // should work even with -Zforce-unstable-if-unmarked -fn main() { } diff --git a/src/test/run-pass/deref-lval.rs b/src/test/run-pass/deref-lval.rs deleted file mode 100644 index f57872f80e0..00000000000 --- a/src/test/run-pass/deref-lval.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -#![feature(box_syntax)] - -use std::cell::Cell; - -pub fn main() { - let x: Box<_> = box Cell::new(5); - x.set(1000); - println!("{}", x.get()); -} diff --git a/src/test/run-pass/deref-mut-on-ref.rs b/src/test/run-pass/deref-mut-on-ref.rs deleted file mode 100644 index a6df5495a27..00000000000 --- a/src/test/run-pass/deref-mut-on-ref.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/deref-on-ref.rs b/src/test/run-pass/deref-on-ref.rs deleted file mode 100644 index 973e61c9d59..00000000000 --- a/src/test/run-pass/deref-on-ref.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/deref-rc.rs b/src/test/run-pass/deref-rc.rs deleted file mode 100644 index 9b4c63b1925..00000000000 --- a/src/test/run-pass/deref-rc.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/deref.rs b/src/test/run-pass/deref.rs deleted file mode 100644 index cad4ede06a5..00000000000 --- a/src/test/run-pass/deref.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(box_syntax)] - -pub fn main() { - let x: Box = box 10; - let _y: isize = *x; -} diff --git a/src/test/run-pass/deriving/auxiliary/derive-no-std.rs b/src/test/run-pass/deriving/auxiliary/derive-no-std.rs deleted file mode 100644 index 3893dc1be07..00000000000 --- a/src/test/run-pass/deriving/auxiliary/derive-no-std.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/deriving/derive-no-std.rs b/src/test/run-pass/deriving/derive-no-std.rs deleted file mode 100644 index 74c73b99cb9..00000000000 --- a/src/test/run-pass/deriving/derive-no-std.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/deriving/derive-partialord-correctness.rs b/src/test/run-pass/deriving/derive-partialord-correctness.rs deleted file mode 100644 index 36763eda169..00000000000 --- a/src/test/run-pass/deriving/derive-partialord-correctness.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-associated-types.rs b/src/test/run-pass/deriving/deriving-associated-types.rs deleted file mode 100644 index 4b1cbe80c50..00000000000 --- a/src/test/run-pass/deriving/deriving-associated-types.rs +++ /dev/null @@ -1,199 +0,0 @@ -// run-pass -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/src/test/run-pass/deriving/deriving-bounds.rs b/src/test/run-pass/deriving/deriving-bounds.rs deleted file mode 100644 index f0b921d0e7c..00000000000 --- a/src/test/run-pass/deriving/deriving-bounds.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -#[derive(Copy, Clone)] -struct Test; - -pub fn main() {} diff --git a/src/test/run-pass/deriving/deriving-clone-array.rs b/src/test/run-pass/deriving/deriving-clone-array.rs deleted file mode 100644 index 4569749df42..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-array.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(dead_code)] -// test for issue #30244 - -#[derive(Copy, Clone)] -struct Array { - arr: [[u8; 256]; 4] -} - -pub fn main() {} diff --git a/src/test/run-pass/deriving/deriving-clone-enum.rs b/src/test/run-pass/deriving/deriving-clone-enum.rs deleted file mode 100644 index 09e74974072..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-enum.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-clone-generic-enum.rs b/src/test/run-pass/deriving/deriving-clone-generic-enum.rs deleted file mode 100644 index a344d7fc43a..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-generic-enum.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-clone-generic-struct.rs b/src/test/run-pass/deriving/deriving-clone-generic-struct.rs deleted file mode 100644 index f6e105555fd..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-generic-struct.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs b/src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs deleted file mode 100644 index 8b9840de172..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#[derive(Clone)] -struct S(T, ()); - -pub fn main() { - let _ = S(1, ()).clone(); -} diff --git a/src/test/run-pass/deriving/deriving-clone-struct.rs b/src/test/run-pass/deriving/deriving-clone-struct.rs deleted file mode 100644 index 7b0a1d20260..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-struct.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-clone-tuple-struct.rs b/src/test/run-pass/deriving/deriving-clone-tuple-struct.rs deleted file mode 100644 index 166f1be55e0..00000000000 --- a/src/test/run-pass/deriving/deriving-clone-tuple-struct.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#[derive(Clone)] -struct S((), ()); - -pub fn main() {} diff --git a/src/test/run-pass/deriving/deriving-cmp-generic-enum.rs b/src/test/run-pass/deriving/deriving-cmp-generic-enum.rs deleted file mode 100644 index 88da4bd066c..00000000000 --- a/src/test/run-pass/deriving/deriving-cmp-generic-enum.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs b/src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs deleted file mode 100644 index eeaf2ff7efa..00000000000 --- a/src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-cmp-generic-struct.rs b/src/test/run-pass/deriving/deriving-cmp-generic-struct.rs deleted file mode 100644 index 538caf439c7..00000000000 --- a/src/test/run-pass/deriving/deriving-cmp-generic-struct.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs b/src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs deleted file mode 100644 index 79f58d4565c..00000000000 --- a/src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs b/src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs deleted file mode 100644 index 140373e9526..00000000000 --- a/src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-copyclone.rs b/src/test/run-pass/deriving/deriving-copyclone.rs deleted file mode 100644 index 78d74a11ffc..00000000000 --- a/src/test/run-pass/deriving/deriving-copyclone.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-default-box.rs b/src/test/run-pass/deriving/deriving-default-box.rs deleted file mode 100644 index 237dbfaa056..00000000000 --- a/src/test/run-pass/deriving/deriving-default-box.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-enum-single-variant.rs b/src/test/run-pass/deriving/deriving-enum-single-variant.rs deleted file mode 100644 index 1c5979c0747..00000000000 --- a/src/test/run-pass/deriving/deriving-enum-single-variant.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs b/src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs deleted file mode 100644 index 5b4b0983623..00000000000 --- a/src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-hash.rs b/src/test/run-pass/deriving/deriving-hash.rs deleted file mode 100644 index 68c68c235ef..00000000000 --- a/src/test/run-pass/deriving/deriving-hash.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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_with_keys(0, 0); - 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/src/test/run-pass/deriving/deriving-in-fn.rs b/src/test/run-pass/deriving/deriving-in-fn.rs deleted file mode 100644 index 8931e94a4f8..00000000000 --- a/src/test/run-pass/deriving/deriving-in-fn.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -pub fn main() { - #[derive(Debug)] - struct Foo { - foo: isize, - } - - let f = Foo { foo: 10 }; - format!("{:?}", f); -} diff --git a/src/test/run-pass/deriving/deriving-in-macro.rs b/src/test/run-pass/deriving/deriving-in-macro.rs deleted file mode 100644 index 46e8e37838d..00000000000 --- a/src/test/run-pass/deriving/deriving-in-macro.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-meta-multiple.rs b/src/test/run-pass/deriving/deriving-meta-multiple.rs deleted file mode 100644 index ad255be8dab..00000000000 --- a/src/test/run-pass/deriving/deriving-meta-multiple.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-meta.rs b/src/test/run-pass/deriving/deriving-meta.rs deleted file mode 100644 index f2ff4f53557..00000000000 --- a/src/test/run-pass/deriving/deriving-meta.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs b/src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs deleted file mode 100644 index e01b5a26fc7..00000000000 --- a/src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-show-2.rs b/src/test/run-pass/deriving/deriving-show-2.rs deleted file mode 100644 index 13d124ed4c3..00000000000 --- a/src/test/run-pass/deriving/deriving-show-2.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-show.rs b/src/test/run-pass/deriving/deriving-show.rs deleted file mode 100644 index eb3a8948fc8..00000000000 --- a/src/test/run-pass/deriving/deriving-show.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-c-enum.rs b/src/test/run-pass/deriving/deriving-via-extension-c-enum.rs deleted file mode 100644 index 7fa1a69d7e0..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-c-enum.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-enum.rs b/src/test/run-pass/deriving/deriving-via-extension-enum.rs deleted file mode 100644 index 6b58fd96622..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-enum.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs b/src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs deleted file mode 100644 index 2d1ca05f4fc..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs b/src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs deleted file mode 100644 index c4037dc2714..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs b/src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs deleted file mode 100644 index 9fb250e8470..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#[derive(PartialEq, Debug)] -struct Foo; - -pub fn main() { - assert_eq!(Foo, Foo); - assert!(!(Foo != Foo)); -} diff --git a/src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs b/src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs deleted file mode 100644 index b6e6f136c75..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs b/src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs deleted file mode 100644 index e84906c96bb..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-struct.rs b/src/test/run-pass/deriving/deriving-via-extension-struct.rs deleted file mode 100644 index f4d8b16a02f..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-struct.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-via-extension-type-params.rs b/src/test/run-pass/deriving/deriving-via-extension-type-params.rs deleted file mode 100644 index a5dec8ee1ab..00000000000 --- a/src/test/run-pass/deriving/deriving-via-extension-type-params.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/deriving/deriving-with-repr-packed.rs b/src/test/run-pass/deriving/deriving-with-repr-packed.rs deleted file mode 100644 index 8ce444be13f..00000000000 --- a/src/test/run-pass/deriving/deriving-with-repr-packed.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/dispatch_from_dyn_zst.rs b/src/test/run-pass/dispatch_from_dyn_zst.rs deleted file mode 100644 index 764f58ce9e8..00000000000 --- a/src/test/run-pass/dispatch_from_dyn_zst.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/diverging-fallback-control-flow.rs b/src/test/run-pass/diverging-fallback-control-flow.rs deleted file mode 100644 index 0f0f787b407..00000000000 --- a/src/test/run-pass/diverging-fallback-control-flow.rs +++ /dev/null @@ -1,101 +0,0 @@ -// 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)] - -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/src/test/run-pass/diverging-fallback-method-chain.rs b/src/test/run-pass/diverging-fallback-method-chain.rs deleted file mode 100644 index ba9f05c64e4..00000000000 --- a/src/test/run-pass/diverging-fallback-method-chain.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/diverging-fallback-option.rs b/src/test/run-pass/diverging-fallback-option.rs deleted file mode 100644 index 46bdfc96dbe..00000000000 --- a/src/test/run-pass/diverging-fallback-option.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/double-ref.rs b/src/test/run-pass/double-ref.rs deleted file mode 100644 index e68b8683376..00000000000 --- a/src/test/run-pass/double-ref.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs b/src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs deleted file mode 100644 index 270d5de7ac8..00000000000 --- a/src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![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/src/test/run-pass/drop/drop-on-empty-block-exit.rs b/src/test/run-pass/drop/drop-on-empty-block-exit.rs deleted file mode 100644 index 1747bf029aa..00000000000 --- a/src/test/run-pass/drop/drop-on-empty-block-exit.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/drop/drop-on-ret.rs b/src/test/run-pass/drop/drop-on-ret.rs deleted file mode 100644 index 290e274f305..00000000000 --- a/src/test/run-pass/drop/drop-on-ret.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/drop/drop-struct-as-object.rs b/src/test/run-pass/drop/drop-struct-as-object.rs deleted file mode 100644 index 1bc3b4c157c..00000000000 --- a/src/test/run-pass/drop/drop-struct-as-object.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/drop/drop-trait-enum.rs b/src/test/run-pass/drop/drop-trait-enum.rs deleted file mode 100644 index aec46575f97..00000000000 --- a/src/test/run-pass/drop/drop-trait-enum.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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/src/test/run-pass/drop/drop-trait-generic.rs b/src/test/run-pass/drop/drop-trait-generic.rs deleted file mode 100644 index cdefb680c75..00000000000 --- a/src/test/run-pass/drop/drop-trait-generic.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/drop/drop-trait.rs b/src/test/run-pass/drop/drop-trait.rs deleted file mode 100644 index d93f7718091..00000000000 --- a/src/test/run-pass/drop/drop-trait.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/drop/drop-uninhabited-enum.rs b/src/test/run-pass/drop/drop-uninhabited-enum.rs deleted file mode 100644 index b3566f68533..00000000000 --- a/src/test/run-pass/drop/drop-uninhabited-enum.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/drop/drop-with-type-ascription-1.rs b/src/test/run-pass/drop/drop-with-type-ascription-1.rs deleted file mode 100644 index e5a1a48df56..00000000000 --- a/src/test/run-pass/drop/drop-with-type-ascription-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/drop/drop-with-type-ascription-2.rs b/src/test/run-pass/drop/drop-with-type-ascription-2.rs deleted file mode 100644 index fb70ad48e88..00000000000 --- a/src/test/run-pass/drop/drop-with-type-ascription-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs b/src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs deleted file mode 100644 index fecfd5edffb..00000000000 --- a/src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/drop/dropck-eyepatch-reorder.rs b/src/test/run-pass/drop/dropck-eyepatch-reorder.rs deleted file mode 100644 index b4605878a54..00000000000 --- a/src/test/run-pass/drop/dropck-eyepatch-reorder.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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/src/test/run-pass/drop/dropck-eyepatch.rs b/src/test/run-pass/drop/dropck-eyepatch.rs deleted file mode 100644 index 9255391e412..00000000000 --- a/src/test/run-pass/drop/dropck-eyepatch.rs +++ /dev/null @@ -1,102 +0,0 @@ -// 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/src/test/run-pass/drop/dropck_legal_cycles.rs b/src/test/run-pass/drop/dropck_legal_cycles.rs deleted file mode 100644 index a4f4c2666ac..00000000000 --- a/src/test/run-pass/drop/dropck_legal_cycles.rs +++ /dev/null @@ -1,1183 +0,0 @@ -// 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/src/test/run-pass/drop/dynamic-drop-async.rs b/src/test/run-pass/drop/dynamic-drop-async.rs deleted file mode 100644 index 9226145d935..00000000000 --- a/src/test/run-pass/drop/dynamic-drop-async.rs +++ /dev/null @@ -1,328 +0,0 @@ -// 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_assignments)] -#![allow(unused_variables)] -#![feature(slice_patterns)] -#![feature(async_await)] - -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; -} - -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)); -} diff --git a/src/test/run-pass/drop/dynamic-drop.rs b/src/test/run-pass/drop/dynamic-drop.rs deleted file mode 100644 index eb1a3f3a9f9..00000000000 --- a/src/test/run-pass/drop/dynamic-drop.rs +++ /dev/null @@ -1,436 +0,0 @@ -// run-pass -#![allow(unused_assignments)] -#![allow(unused_variables)] - -// ignore-wasm32-bare compiled with panic=abort by default - -#![feature(generators, generator_trait, untagged_unions)] -#![feature(slice_patterns)] - -use std::cell::{Cell, RefCell}; -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; -} - -#[allow(unions_with_drop_fields)] -union Boxy { - a: T, - b: T, -} - -fn union1(a: &Allocator) { - unsafe { - let mut u = Boxy { a: a.alloc() }; - u.b = a.alloc(); - drop(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 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| { - 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_nopanic(|a| union1(a)); -} diff --git a/src/test/run-pass/drop/no-drop-flag-size.rs b/src/test/run-pass/drop/no-drop-flag-size.rs deleted file mode 100644 index 103e70ef6ee..00000000000 --- a/src/test/run-pass/drop/no-drop-flag-size.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/drop/nondrop-cycle.rs b/src/test/run-pass/drop/nondrop-cycle.rs deleted file mode 100644 index 29070f917e4..00000000000 --- a/src/test/run-pass/drop/nondrop-cycle.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/dupe-first-attr.rc b/src/test/run-pass/dupe-first-attr.rc deleted file mode 100644 index 8b7025b7be7..00000000000 --- a/src/test/run-pass/dupe-first-attr.rc +++ /dev/null @@ -1,24 +0,0 @@ -// Regression test for a problem with the first mod attribute -// being applied to every mod - -// pretty-expanded FIXME #23616 - -#[cfg(target_os = "linux")] -mod hello; - -#[cfg(target_os = "macos")] -mod hello; - -#[cfg(target_os = "windows")] -mod hello; - -#[cfg(target_os = "freebsd")] -mod hello; - -#[cfg(target_os = "dragonfly")] -mod hello; - -#[cfg(target_os = "android")] -mod hello; - -pub fn main() { } diff --git a/src/test/run-pass/duplicated-external-mods.rs b/src/test/run-pass/duplicated-external-mods.rs deleted file mode 100644 index 05a279a3014..00000000000 --- a/src/test/run-pass/duplicated-external-mods.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs b/src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs deleted file mode 100644 index 24d83eb5343..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs b/src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs deleted file mode 100644 index 683fa6850fd..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-coercions.rs b/src/test/run-pass/dynamically-sized-types/dst-coercions.rs deleted file mode 100644 index 66688e93fb8..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-coercions.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs b/src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs deleted file mode 100644 index 1d62f42bd4a..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-deref.rs b/src/test/run-pass/dynamically-sized-types/dst-deref.rs deleted file mode 100644 index 0a350bac14a..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-deref.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-field-align.rs b/src/test/run-pass/dynamically-sized-types/dst-field-align.rs deleted file mode 100644 index 6c338e99912..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-field-align.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-index.rs b/src/test/run-pass/dynamically-sized-types/dst-index.rs deleted file mode 100644 index 980d99a6d6c..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-index.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs b/src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs deleted file mode 100644 index 0a6c49111fe..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-raw.rs b/src/test/run-pass/dynamically-sized-types/dst-raw.rs deleted file mode 100644 index 0893b02e74e..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-raw.rs +++ /dev/null @@ -1,138 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs b/src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs deleted file mode 100644 index 6ca07fcf8da..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-struct.rs b/src/test/run-pass/dynamically-sized-types/dst-struct.rs deleted file mode 100644 index 25ec07b88a6..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-struct.rs +++ /dev/null @@ -1,122 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs b/src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs deleted file mode 100644 index 70bcc3de07d..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-trait.rs b/src/test/run-pass/dynamically-sized-types/dst-trait.rs deleted file mode 100644 index ec6bc72192d..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-trait.rs +++ /dev/null @@ -1,105 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs b/src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs deleted file mode 100644 index 606689da0c2..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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/src/test/run-pass/dynamically-sized-types/dst-tuple.rs b/src/test/run-pass/dynamically-sized-types/dst-tuple.rs deleted file mode 100644 index f70a45a1b35..00000000000 --- a/src/test/run-pass/dynamically-sized-types/dst-tuple.rs +++ /dev/null @@ -1,120 +0,0 @@ -// 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/src/test/run-pass/early-ret-binop-add.rs b/src/test/run-pass/early-ret-binop-add.rs deleted file mode 100644 index 2b5df52a51c..00000000000 --- a/src/test/run-pass/early-ret-binop-add.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/early-vtbl-resolution.rs b/src/test/run-pass/early-vtbl-resolution.rs deleted file mode 100644 index f4b69c14095..00000000000 --- a/src/test/run-pass/early-vtbl-resolution.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/edition-keywords-2015-2015.rs b/src/test/run-pass/edition-keywords-2015-2015.rs deleted file mode 100644 index 943d203b806..00000000000 --- a/src/test/run-pass/edition-keywords-2015-2015.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/edition-keywords-2015-2018.rs b/src/test/run-pass/edition-keywords-2015-2018.rs deleted file mode 100644 index 8c3397c951d..00000000000 --- a/src/test/run-pass/edition-keywords-2015-2018.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/edition-keywords-2018-2015.rs b/src/test/run-pass/edition-keywords-2018-2015.rs deleted file mode 100644 index 2cb2dfb18a0..00000000000 --- a/src/test/run-pass/edition-keywords-2018-2015.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/edition-keywords-2018-2018.rs b/src/test/run-pass/edition-keywords-2018-2018.rs deleted file mode 100644 index 5043440aa16..00000000000 --- a/src/test/run-pass/edition-keywords-2018-2018.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/else-if.rs b/src/test/run-pass/else-if.rs deleted file mode 100644 index 77d8d1abfaf..00000000000 --- a/src/test/run-pass/else-if.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/empty-allocation-non-null.rs b/src/test/run-pass/empty-allocation-non-null.rs deleted file mode 100644 index 925bddd5edd..00000000000 --- a/src/test/run-pass/empty-allocation-non-null.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/empty-allocation-rvalue-non-null.rs b/src/test/run-pass/empty-allocation-rvalue-non-null.rs deleted file mode 100644 index 2f5a5c4bbc6..00000000000 --- a/src/test/run-pass/empty-allocation-rvalue-non-null.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -pub fn main() { - let x = *Box::new(()); -} diff --git a/src/test/run-pass/empty-type-parameter-list.rs b/src/test/run-pass/empty-type-parameter-list.rs deleted file mode 100644 index e168cd03b27..00000000000 --- a/src/test/run-pass/empty-type-parameter-list.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/empty_global_asm.rs b/src/test/run-pass/empty_global_asm.rs deleted file mode 100644 index efbe2b2eb67..00000000000 --- a/src/test/run-pass/empty_global_asm.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/env-args-reverse-iterator.rs b/src/test/run-pass/env-args-reverse-iterator.rs deleted file mode 100644 index 0ffd74f87ab..00000000000 --- a/src/test/run-pass/env-args-reverse-iterator.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/env-funky-keys.rs b/src/test/run-pass/env-funky-keys.rs deleted file mode 100644 index 4faceb53266..00000000000 --- a/src/test/run-pass/env-funky-keys.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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 -// 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/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs deleted file mode 100644 index a75be48fd55..00000000000 --- a/src/test/run-pass/env-home-dir.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/env-null-vars.rs b/src/test/run-pass/env-null-vars.rs deleted file mode 100644 index 10582a8a514..00000000000 --- a/src/test/run-pass/env-null-vars.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/env-vars.rs b/src/test/run-pass/env-vars.rs deleted file mode 100644 index 2ea906788e8..00000000000 --- a/src/test/run-pass/env-vars.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs deleted file mode 100644 index 5f7feb5347b..00000000000 --- a/src/test/run-pass/epoch-gate-feature.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/eq-multidispatch.rs b/src/test/run-pass/eq-multidispatch.rs deleted file mode 100644 index 69d83f496b3..00000000000 --- a/src/test/run-pass/eq-multidispatch.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/estr-uniq.rs b/src/test/run-pass/estr-uniq.rs deleted file mode 100644 index 1d0a4273953..00000000000 --- a/src/test/run-pass/estr-uniq.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/exec-env.rs b/src/test/run-pass/exec-env.rs deleted file mode 100644 index 230fac10d33..00000000000 --- a/src/test/run-pass/exec-env.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/existential_type.rs b/src/test/run-pass/existential_type.rs deleted file mode 100644 index c2cf0eeed3d..00000000000 --- a/src/test/run-pass/existential_type.rs +++ /dev/null @@ -1,89 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![allow(unused_assignments)] -#![allow(unused_variables)] -#![feature(existential_type)] - -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 -existential type Foo: std::fmt::Display; - -fn foo() -> Foo { - "foo" -} - -// two definitions -existential type Bar: std::fmt::Display; - -fn bar1() -> Bar { - "bar1" -} - -fn bar2() -> Bar { - "bar2" -} - -// definition in submodule -existential type Boo: std::fmt::Display; - -mod boo { - pub fn boo() -> super::Boo { - "boo" - } -} - -existential type MyIter: 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! -existential type MyOtherIter: Iterator; - -fn my_other_iter(u: U) -> MyOtherIter { - std::iter::once(u) -} - -trait Trait {} -existential type GenericBound<'a, T: Trait>: Sized + 'a; - -fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { - t -} - -mod pass_through { - pub existential type Passthrough: Sized + 'static; - - fn define_passthrough(t: T) -> Passthrough { - t - } -} - -fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { - x -} diff --git a/src/test/run-pass/explicit-i-suffix.rs b/src/test/run-pass/explicit-i-suffix.rs deleted file mode 100644 index 40c7e475104..00000000000 --- a/src/test/run-pass/explicit-i-suffix.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/export-glob-imports-target.rs b/src/test/run-pass/export-glob-imports-target.rs deleted file mode 100644 index 4df807ea4c9..00000000000 --- a/src/test/run-pass/export-glob-imports-target.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/export-multi.rs b/src/test/run-pass/export-multi.rs deleted file mode 100644 index 02bdbe8afff..00000000000 --- a/src/test/run-pass/export-multi.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/export-non-interference2.rs b/src/test/run-pass/export-non-interference2.rs deleted file mode 100644 index 6d18b03891a..00000000000 --- a/src/test/run-pass/export-non-interference2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/export-non-interference3.rs b/src/test/run-pass/export-non-interference3.rs deleted file mode 100644 index 0d6b6369f94..00000000000 --- a/src/test/run-pass/export-non-interference3.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/expr-block-fn.rs b/src/test/run-pass/expr-block-fn.rs deleted file mode 100644 index 1cac2cac0ac..00000000000 --- a/src/test/run-pass/expr-block-fn.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs deleted file mode 100644 index c14191f2ffc..00000000000 --- a/src/test/run-pass/expr-block-generic-unique1.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs deleted file mode 100644 index 90ebc02931a..00000000000 --- a/src/test/run-pass/expr-block-generic-unique2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs deleted file mode 100644 index ec93f59722d..00000000000 --- a/src/test/run-pass/expr-block-generic.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass - -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/src/test/run-pass/expr-block-slot.rs b/src/test/run-pass/expr-block-slot.rs deleted file mode 100644 index 54bcbb328b0..00000000000 --- a/src/test/run-pass/expr-block-slot.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/expr-block-unique.rs b/src/test/run-pass/expr-block-unique.rs deleted file mode 100644 index fe1a7d9f1fb..00000000000 --- a/src/test/run-pass/expr-block-unique.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -#![feature(box_syntax)] - -pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); } diff --git a/src/test/run-pass/expr-block.rs b/src/test/run-pass/expr-block.rs deleted file mode 100644 index 549ccf9774f..00000000000 --- a/src/test/run-pass/expr-block.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/expr-copy.rs b/src/test/run-pass/expr-copy.rs deleted file mode 100644 index 1c6ae03810f..00000000000 --- a/src/test/run-pass/expr-copy.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/expr-empty-ret.rs b/src/test/run-pass/expr-empty-ret.rs deleted file mode 100644 index ce8ffaf94d0..00000000000 --- a/src/test/run-pass/expr-empty-ret.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/expr-fn.rs b/src/test/run-pass/expr-fn.rs deleted file mode 100644 index af809f563fc..00000000000 --- a/src/test/run-pass/expr-fn.rs +++ /dev/null @@ -1,61 +0,0 @@ -// run-pass - -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/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs deleted file mode 100644 index 32ed6d9bee0..00000000000 --- a/src/test/run-pass/expr-if-generic.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/expr-if-panic-all.rs b/src/test/run-pass/expr-if-panic-all.rs deleted file mode 100644 index f915a7d9da0..00000000000 --- a/src/test/run-pass/expr-if-panic-all.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/expr-if-panic.rs b/src/test/run-pass/expr-if-panic.rs deleted file mode 100644 index 6069cd835e1..00000000000 --- a/src/test/run-pass/expr-if-panic.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/expr-if-unique.rs b/src/test/run-pass/expr-if-unique.rs deleted file mode 100644 index 509d069d40f..00000000000 --- a/src/test/run-pass/expr-if-unique.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/expr-if.rs b/src/test/run-pass/expr-if.rs deleted file mode 100644 index 2b8474ff453..00000000000 --- a/src/test/run-pass/expr-if.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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/src/test/run-pass/expr-scope.rs b/src/test/run-pass/expr-scope.rs deleted file mode 100644 index 9976b6814c0..00000000000 --- a/src/test/run-pass/expr-scope.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// Regression test for issue #762 - -// pretty-expanded FIXME #23616 - -pub fn f() { } -pub fn main() { return ::f(); } diff --git a/src/test/run-pass/ext-expand-inner-exprs.rs b/src/test/run-pass/ext-expand-inner-exprs.rs deleted file mode 100644 index 5bbdf5ec956..00000000000 --- a/src/test/run-pass/ext-expand-inner-exprs.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -static FOO : &'static str = concat!(concat!("hel", "lo"), "world"); - -pub fn main() { - assert_eq!(FOO, "helloworld"); -} diff --git a/src/test/run-pass/extend-for-unit.rs b/src/test/run-pass/extend-for-unit.rs deleted file mode 100644 index 01d743f70bc..00000000000 --- a/src/test/run-pass/extend-for-unit.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/exterior.rs b/src/test/run-pass/exterior.rs deleted file mode 100644 index 6f2c37926be..00000000000 --- a/src/test/run-pass/exterior.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - -#![allow(dead_code)] - - -use std::cell::Cell; - -#[derive(Copy, Clone)] -struct Point {x: isize, y: isize, z: isize} - -fn f(p: &Cell) { - assert_eq!(p.get().z, 12); - p.set(Point {x: 10, y: 11, z: 13}); - assert_eq!(p.get().z, 13); -} - -pub fn main() { - let a: Point = Point {x: 10, y: 11, z: 12}; - let b: &Cell = &Cell::new(a); - assert_eq!(b.get().z, 12); - f(b); - assert_eq!(a.z, 12); - assert_eq!(b.get().z, 13); -} diff --git a/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs deleted file mode 100644 index d4568d38e25..00000000000 --- a/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![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/src/test/run-pass/extern/auxiliary/extern-take-value.rs b/src/test/run-pass/extern/auxiliary/extern-take-value.rs deleted file mode 100644 index 869e794cc8a..00000000000 --- a/src/test/run-pass/extern/auxiliary/extern-take-value.rs +++ /dev/null @@ -1,5 +0,0 @@ -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/src/test/run-pass/extern/auxiliary/extern_calling_convention.rs b/src/test/run-pass/extern/auxiliary/extern_calling_convention.rs deleted file mode 100644 index 968b1a25510..00000000000 --- a/src/test/run-pass/extern/auxiliary/extern_calling_convention.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs b/src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs deleted file mode 100644 index 7357f59700e..00000000000 --- a/src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type="lib"] - -pub mod extern_mod_ordering_lib { - pub fn f() {} -} diff --git a/src/test/run-pass/extern/auxiliary/fat_drop.rs b/src/test/run-pass/extern/auxiliary/fat_drop.rs deleted file mode 100644 index 768d29876b9..00000000000 --- a/src/test/run-pass/extern/auxiliary/fat_drop.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/src/test/run-pass/extern/extern-1.rs b/src/test/run-pass/extern/extern-1.rs deleted file mode 100644 index eb9aabc87bc..00000000000 --- a/src/test/run-pass/extern/extern-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -extern fn f() { -} - -pub fn main() { -} diff --git a/src/test/run-pass/extern/extern-call-deep.rs b/src/test/run-pass/extern/extern-call-deep.rs deleted file mode 100644 index 81f884dada9..00000000000 --- a/src/test/run-pass/extern/extern-call-deep.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/extern/extern-call-deep2.rs b/src/test/run-pass/extern/extern-call-deep2.rs deleted file mode 100644 index b31489b1e10..00000000000 --- a/src/test/run-pass/extern/extern-call-deep2.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/extern/extern-call-direct.rs b/src/test/run-pass/extern/extern-call-direct.rs deleted file mode 100644 index 72041764215..00000000000 --- a/src/test/run-pass/extern/extern-call-direct.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/extern/extern-call-indirect.rs b/src/test/run-pass/extern/extern-call-indirect.rs deleted file mode 100644 index 158b54e4b8c..00000000000 --- a/src/test/run-pass/extern/extern-call-indirect.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/extern/extern-call-scrub.rs b/src/test/run-pass/extern/extern-call-scrub.rs deleted file mode 100644 index a7b1065c9e1..00000000000 --- a/src/test/run-pass/extern/extern-call-scrub.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/extern/extern-calling-convention-test.rs b/src/test/run-pass/extern/extern-calling-convention-test.rs deleted file mode 100644 index 7231a7cde85..00000000000 --- a/src/test/run-pass/extern/extern-calling-convention-test.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/extern/extern-compare-with-return-type.rs b/src/test/run-pass/extern/extern-compare-with-return-type.rs deleted file mode 100644 index 6c9ed3760f6..00000000000 --- a/src/test/run-pass/extern/extern-compare-with-return-type.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/extern/extern-crosscrate.rs b/src/test/run-pass/extern/extern-crosscrate.rs deleted file mode 100644 index 123ce20ca26..00000000000 --- a/src/test/run-pass/extern/extern-crosscrate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/extern/extern-foreign-crate.rs b/src/test/run-pass/extern/extern-foreign-crate.rs deleted file mode 100644 index 7f774c44277..00000000000 --- a/src/test/run-pass/extern/extern-foreign-crate.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -extern crate std as mystd; - -pub fn main() {} diff --git a/src/test/run-pass/extern/extern-methods.rs b/src/test/run-pass/extern/extern-methods.rs deleted file mode 100644 index b142ec59e88..00000000000 --- a/src/test/run-pass/extern/extern-methods.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass -// ignore-arm -// ignore-aarch64 - -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/src/test/run-pass/extern/extern-mod-abi.rs b/src/test/run-pass/extern/extern-mod-abi.rs deleted file mode 100644 index c543394cca0..00000000000 --- a/src/test/run-pass/extern/extern-mod-abi.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -extern "C" { - fn pow(x: f64, y: f64) -> f64; -} - -pub fn main() {} diff --git a/src/test/run-pass/extern/extern-mod-ordering-exe.rs b/src/test/run-pass/extern/extern-mod-ordering-exe.rs deleted file mode 100644 index d7cc4dffb44..00000000000 --- a/src/test/run-pass/extern/extern-mod-ordering-exe.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-TwoU16s.rs b/src/test/run-pass/extern/extern-pass-TwoU16s.rs deleted file mode 100644 index 285bce2e19c..00000000000 --- a/src/test/run-pass/extern/extern-pass-TwoU16s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-TwoU32s.rs b/src/test/run-pass/extern/extern-pass-TwoU32s.rs deleted file mode 100644 index fb18aa8d22f..00000000000 --- a/src/test/run-pass/extern/extern-pass-TwoU32s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-TwoU64s.rs b/src/test/run-pass/extern/extern-pass-TwoU64s.rs deleted file mode 100644 index 419648263aa..00000000000 --- a/src/test/run-pass/extern/extern-pass-TwoU64s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-TwoU8s.rs b/src/test/run-pass/extern/extern-pass-TwoU8s.rs deleted file mode 100644 index 53a6a0f29f8..00000000000 --- a/src/test/run-pass/extern/extern-pass-TwoU8s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-char.rs b/src/test/run-pass/extern/extern-pass-char.rs deleted file mode 100644 index 22f841b4552..00000000000 --- a/src/test/run-pass/extern/extern-pass-char.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-double.rs b/src/test/run-pass/extern/extern-pass-double.rs deleted file mode 100644 index dbd0a2dfa48..00000000000 --- a/src/test/run-pass/extern/extern-pass-double.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-empty.rs b/src/test/run-pass/extern/extern-pass-empty.rs deleted file mode 100644 index 07099a24204..00000000000 --- a/src/test/run-pass/extern/extern-pass-empty.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-u32.rs b/src/test/run-pass/extern/extern-pass-u32.rs deleted file mode 100644 index f2efdb7d366..00000000000 --- a/src/test/run-pass/extern/extern-pass-u32.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/extern/extern-pass-u64.rs b/src/test/run-pass/extern/extern-pass-u64.rs deleted file mode 100644 index 975446d430c..00000000000 --- a/src/test/run-pass/extern/extern-pass-u64.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/extern/extern-prelude-core.rs b/src/test/run-pass/extern/extern-prelude-core.rs deleted file mode 100644 index f0d43404b00..00000000000 --- a/src/test/run-pass/extern/extern-prelude-core.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -#![feature(extern_prelude, 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/src/test/run-pass/extern/extern-prelude-core.stderr b/src/test/run-pass/extern/extern-prelude-core.stderr deleted file mode 100644 index f90eb933d3f..00000000000 --- a/src/test/run-pass/extern/extern-prelude-core.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable - --> $DIR/extern-prelude-core.rs:2:12 - | -LL | #![feature(extern_prelude, lang_items, start)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(stable_features)]` on by default - diff --git a/src/test/run-pass/extern/extern-prelude-no-speculative.rs b/src/test/run-pass/extern/extern-prelude-no-speculative.rs deleted file mode 100644 index cc00737ab59..00000000000 --- a/src/test/run-pass/extern/extern-prelude-no-speculative.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// compile-flags: --extern LooksLikeExternCrate - -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/src/test/run-pass/extern/extern-prelude-std.rs b/src/test/run-pass/extern/extern-prelude-std.rs deleted file mode 100644 index 3d28448ee86..00000000000 --- a/src/test/run-pass/extern/extern-prelude-std.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![feature(extern_prelude)] - -mod foo { - pub fn test() { - let x = std::cmp::min(2, 3); - assert_eq!(x, 2); - } -} - -fn main() { - foo::test(); -} diff --git a/src/test/run-pass/extern/extern-prelude-std.stderr b/src/test/run-pass/extern/extern-prelude-std.stderr deleted file mode 100644 index 73b1dcfd5e1..00000000000 --- a/src/test/run-pass/extern/extern-prelude-std.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable - --> $DIR/extern-prelude-std.rs:2:12 - | -LL | #![feature(extern_prelude)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(stable_features)]` on by default - diff --git a/src/test/run-pass/extern/extern-pub.rs b/src/test/run-pass/extern/extern-pub.rs deleted file mode 100644 index c97e04b0755..00000000000 --- a/src/test/run-pass/extern/extern-pub.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -extern { - pub fn free(p: *const u8); -} - -pub fn main() { -} diff --git a/src/test/run-pass/extern/extern-return-TwoU16s.rs b/src/test/run-pass/extern/extern-return-TwoU16s.rs deleted file mode 100644 index dd884ee77fe..00000000000 --- a/src/test/run-pass/extern/extern-return-TwoU16s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/extern/extern-return-TwoU32s.rs b/src/test/run-pass/extern/extern-return-TwoU32s.rs deleted file mode 100644 index d6aaf5c9eaf..00000000000 --- a/src/test/run-pass/extern/extern-return-TwoU32s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/extern/extern-return-TwoU64s.rs b/src/test/run-pass/extern/extern-return-TwoU64s.rs deleted file mode 100644 index c5e4ebadc18..00000000000 --- a/src/test/run-pass/extern/extern-return-TwoU64s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/extern/extern-return-TwoU8s.rs b/src/test/run-pass/extern/extern-return-TwoU8s.rs deleted file mode 100644 index a7cd21b2073..00000000000 --- a/src/test/run-pass/extern/extern-return-TwoU8s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/extern/extern-rust.rs b/src/test/run-pass/extern/extern-rust.rs deleted file mode 100644 index 0cb190257be..00000000000 --- a/src/test/run-pass/extern/extern-rust.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/extern/extern-take-value.rs b/src/test/run-pass/extern/extern-take-value.rs deleted file mode 100644 index c09a774361f..00000000000 --- a/src/test/run-pass/extern/extern-take-value.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/extern/extern-thiscall.rs b/src/test/run-pass/extern/extern-thiscall.rs deleted file mode 100644 index e556c0512e9..00000000000 --- a/src/test/run-pass/extern/extern-thiscall.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -// ignore-arm -// ignore-aarch64 - -#![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/src/test/run-pass/extern/extern-types-inherent-impl.rs b/src/test/run-pass/extern/extern-types-inherent-impl.rs deleted file mode 100644 index fc98f55dc07..00000000000 --- a/src/test/run-pass/extern/extern-types-inherent-impl.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Test that inherent impls can be defined for extern types. - -#![feature(extern_types)] - -extern { - type A; -} - -impl A { - fn foo(&self) { } -} - -fn use_foo(x: &A) { - x.foo(); -} - -fn main() { } diff --git a/src/test/run-pass/extern/extern-types-manual-sync-send.rs b/src/test/run-pass/extern/extern-types-manual-sync-send.rs deleted file mode 100644 index ec63e5d40b9..00000000000 --- a/src/test/run-pass/extern/extern-types-manual-sync-send.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/extern/extern-types-pointer-cast.rs b/src/test/run-pass/extern/extern-types-pointer-cast.rs deleted file mode 100644 index a4ebd3cf71e..00000000000 --- a/src/test/run-pass/extern/extern-types-pointer-cast.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/extern/extern-types-size_of_val.rs b/src/test/run-pass/extern/extern-types-size_of_val.rs deleted file mode 100644 index 1c965609758..00000000000 --- a/src/test/run-pass/extern/extern-types-size_of_val.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/extern/extern-types-thin-pointer.rs b/src/test/run-pass/extern/extern-types-thin-pointer.rs deleted file mode 100644 index 83c35f7af78..00000000000 --- a/src/test/run-pass/extern/extern-types-thin-pointer.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/extern/extern-types-trait-impl.rs b/src/test/run-pass/extern/extern-types-trait-impl.rs deleted file mode 100644 index 6cce6c723c5..00000000000 --- a/src/test/run-pass/extern/extern-types-trait-impl.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/extern/extern-vectorcall.rs b/src/test/run-pass/extern/extern-vectorcall.rs deleted file mode 100644 index 1427a8f55cb..00000000000 --- a/src/test/run-pass/extern/extern-vectorcall.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -// ignore-arm -// ignore-aarch64 - -#![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/src/test/run-pass/extern/extern_fat_drop.rs b/src/test/run-pass/extern/extern_fat_drop.rs deleted file mode 100644 index 1cd12c2cab3..00000000000 --- a/src/test/run-pass/extern/extern_fat_drop.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/extoption_env-not-defined.rs b/src/test/run-pass/extoption_env-not-defined.rs deleted file mode 100644 index 4014902ffed..00000000000 --- a/src/test/run-pass/extoption_env-not-defined.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -pub fn main() { - assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none()); -} diff --git a/src/test/run-pass/fact.rs b/src/test/run-pass/fact.rs deleted file mode 100644 index c6c2f57e75c..00000000000 --- a/src/test/run-pass/fact.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/fat-lto.rs b/src/test/run-pass/fat-lto.rs deleted file mode 100644 index c8d8095a265..00000000000 --- a/src/test/run-pass/fat-lto.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// compile-flags: -Clto=fat -// no-prefer-dynamic - -fn main() { - println!("hello!"); -} diff --git a/src/test/run-pass/fds-are-cloexec.rs b/src/test/run-pass/fds-are-cloexec.rs deleted file mode 100644 index 2010b5b6680..00000000000 --- a/src/test/run-pass/fds-are-cloexec.rs +++ /dev/null @@ -1,83 +0,0 @@ -// 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/src/test/run-pass/filter-block-view-items.rs b/src/test/run-pass/filter-block-view-items.rs deleted file mode 100644 index e63aa91577b..00000000000 --- a/src/test/run-pass/filter-block-view-items.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/fixup-deref-mut.rs b/src/test/run-pass/fixup-deref-mut.rs deleted file mode 100644 index 6b2fd72b895..00000000000 --- a/src/test/run-pass/fixup-deref-mut.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/auto-loop.rs b/src/test/run-pass/for-loop-while/auto-loop.rs deleted file mode 100644 index f02ac43c734..00000000000 --- a/src/test/run-pass/for-loop-while/auto-loop.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/break-value.rs b/src/test/run-pass/for-loop-while/break-value.rs deleted file mode 100644 index 9fc49fa8181..00000000000 --- a/src/test/run-pass/for-loop-while/break-value.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/break.rs b/src/test/run-pass/for-loop-while/break.rs deleted file mode 100644 index 427b1b7a063..00000000000 --- a/src/test/run-pass/for-loop-while/break.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-destruct.rs b/src/test/run-pass/for-loop-while/for-destruct.rs deleted file mode 100644 index 7ca8d4ded25..00000000000 --- a/src/test/run-pass/for-loop-while/for-destruct.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-goofiness.rs b/src/test/run-pass/for-loop-while/for-loop-goofiness.rs deleted file mode 100644 index 872ab168bb2..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-goofiness.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs b/src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs deleted file mode 100644 index 38c34d2dc2e..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -fn main() { - // Check that the tail statement in the body unifies with something - for _ in 0..3 { - #[allow(deprecated)] - unsafe { std::mem::uninitialized() } - } - - // Check that the tail statement in the body can be unit - for _ in 0..3 { - () - } -} diff --git a/src/test/run-pass/for-loop-while/for-loop-into-iterator.rs b/src/test/run-pass/for-loop-while/for-loop-into-iterator.rs deleted file mode 100644 index 199d4ddb299..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-into-iterator.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs b/src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs deleted file mode 100644 index 6a38764a131..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-macro.rs b/src/test/run-pass/for-loop-while/for-loop-macro.rs deleted file mode 100644 index 5abccd2a141..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-macro.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs b/src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs deleted file mode 100644 index a3d82ace9e2..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs +++ /dev/null @@ -1,6 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-no-std.rs b/src/test/run-pass/for-loop-while/for-loop-no-std.rs deleted file mode 100644 index 65a33c5f16f..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-no-std.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/for-loop-panic.rs b/src/test/run-pass/for-loop-while/for-loop-panic.rs deleted file mode 100644 index ac607d6d731..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-panic.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass - - -pub fn main() { let x: Vec = Vec::new(); for _ in &x { panic!("moop"); } } diff --git a/src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs deleted file mode 100644 index a1e9b1ed87d..00000000000 --- a/src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs deleted file mode 100644 index 7de6a4f8acb..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs deleted file mode 100644 index 5d690807e05..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs deleted file mode 100644 index 9f2ca05cdb6..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs deleted file mode 100644 index 78af195bc20..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs deleted file mode 100644 index 8a95f160a1a..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-external-iterators.rs b/src/test/run-pass/for-loop-while/foreach-external-iterators.rs deleted file mode 100644 index 24ecfe9b60d..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-external-iterators.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-nested.rs b/src/test/run-pass/for-loop-while/foreach-nested.rs deleted file mode 100644 index bb6edbc0797..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-nested.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-put-structured.rs b/src/test/run-pass/for-loop-while/foreach-put-structured.rs deleted file mode 100644 index 3a47fcf3415..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-put-structured.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs b/src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs deleted file mode 100644 index a8d42a789ba..00000000000 --- a/src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/label_break_value.rs b/src/test/run-pass/for-loop-while/label_break_value.rs deleted file mode 100644 index eb5be7742e0..00000000000 --- a/src/test/run-pass/for-loop-while/label_break_value.rs +++ /dev/null @@ -1,116 +0,0 @@ -// 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 { - 'e: { - 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/src/test/run-pass/for-loop-while/labeled-break.rs b/src/test/run-pass/for-loop-while/labeled-break.rs deleted file mode 100644 index 4dacc57574f..00000000000 --- a/src/test/run-pass/for-loop-while/labeled-break.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/linear-for-loop.rs b/src/test/run-pass/for-loop-while/linear-for-loop.rs deleted file mode 100644 index 3c573db1d77..00000000000 --- a/src/test/run-pass/for-loop-while/linear-for-loop.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs b/src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs deleted file mode 100644 index 11b6971656f..00000000000 --- a/src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/liveness-loop-break.rs b/src/test/run-pass/for-loop-while/liveness-loop-break.rs deleted file mode 100644 index 60a63bccb10..00000000000 --- a/src/test/run-pass/for-loop-while/liveness-loop-break.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -fn test() { - let v; - loop { - v = 3; - break; - } - println!("{}", v); -} - -pub fn main() { - test(); -} diff --git a/src/test/run-pass/for-loop-while/liveness-move-in-loop.rs b/src/test/run-pass/for-loop-while/liveness-move-in-loop.rs deleted file mode 100644 index ce73d6335cb..00000000000 --- a/src/test/run-pass/for-loop-while/liveness-move-in-loop.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-break-cont-1.rs b/src/test/run-pass/for-loop-while/loop-break-cont-1.rs deleted file mode 100644 index f207746f085..00000000000 --- a/src/test/run-pass/for-loop-while/loop-break-cont-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -pub fn main() { - let _i = 0_usize; - loop { - break; - } - assert!(true); -} diff --git a/src/test/run-pass/for-loop-while/loop-break-cont.rs b/src/test/run-pass/for-loop-while/loop-break-cont.rs deleted file mode 100644 index 92d5a32c62b..00000000000 --- a/src/test/run-pass/for-loop-while/loop-break-cont.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-break-value.rs b/src/test/run-pass/for-loop-while/loop-break-value.rs deleted file mode 100644 index e1edbbb929e..00000000000 --- a/src/test/run-pass/for-loop-while/loop-break-value.rs +++ /dev/null @@ -1,138 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-diverges.rs b/src/test/run-pass/for-loop-while/loop-diverges.rs deleted file mode 100644 index f657bf9e0b3..00000000000 --- a/src/test/run-pass/for-loop-while/loop-diverges.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-label-shadowing.rs b/src/test/run-pass/for-loop-while/loop-label-shadowing.rs deleted file mode 100644 index acb53e254bb..00000000000 --- a/src/test/run-pass/for-loop-while/loop-label-shadowing.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// Issue #12512. - -// pretty-expanded FIXME #23616 - -fn main() { - let mut foo = Vec::new(); - 'foo: for i in &[1, 2, 3] { - foo.push(*i); - } -} diff --git a/src/test/run-pass/for-loop-while/loop-labeled-break-value.rs b/src/test/run-pass/for-loop-while/loop-labeled-break-value.rs deleted file mode 100644 index cc8f826983b..00000000000 --- a/src/test/run-pass/for-loop-while/loop-labeled-break-value.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs b/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs deleted file mode 100644 index 1b5db20129d..00000000000 --- a/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/loop-scope.rs b/src/test/run-pass/for-loop-while/loop-scope.rs deleted file mode 100644 index 73324a3e1bd..00000000000 --- a/src/test/run-pass/for-loop-while/loop-scope.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-cont.rs b/src/test/run-pass/for-loop-while/while-cont.rs deleted file mode 100644 index a864e8ef70a..00000000000 --- a/src/test/run-pass/for-loop-while/while-cont.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-flow-graph.rs b/src/test/run-pass/for-loop-while/while-flow-graph.rs deleted file mode 100644 index 1748964a7b2..00000000000 --- a/src/test/run-pass/for-loop-while/while-flow-graph.rs +++ /dev/null @@ -1,6 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-label.rs b/src/test/run-pass/for-loop-while/while-label.rs deleted file mode 100644 index 5abc41daf94..00000000000 --- a/src/test/run-pass/for-loop-while/while-label.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-let.rs b/src/test/run-pass/for-loop-while/while-let.rs deleted file mode 100644 index b9d70ff0b9d..00000000000 --- a/src/test/run-pass/for-loop-while/while-let.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-loop-constraints-2.rs b/src/test/run-pass/for-loop-while/while-loop-constraints-2.rs deleted file mode 100644 index 3c5cdf06cd8..00000000000 --- a/src/test/run-pass/for-loop-while/while-loop-constraints-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-prelude-drop.rs b/src/test/run-pass/for-loop-while/while-prelude-drop.rs deleted file mode 100644 index 196b9daf6ec..00000000000 --- a/src/test/run-pass/for-loop-while/while-prelude-drop.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while-with-break.rs b/src/test/run-pass/for-loop-while/while-with-break.rs deleted file mode 100644 index a9d52dda544..00000000000 --- a/src/test/run-pass/for-loop-while/while-with-break.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/for-loop-while/while.rs b/src/test/run-pass/for-loop-while/while.rs deleted file mode 100644 index 90f718a3483..00000000000 --- a/src/test/run-pass/for-loop-while/while.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/foreign/auxiliary/fn-abi.rs b/src/test/run-pass/foreign/auxiliary/fn-abi.rs deleted file mode 100644 index 25c9e1b4ca3..00000000000 --- a/src/test/run-pass/foreign/auxiliary/fn-abi.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[no_mangle] -pub extern fn foo() {} diff --git a/src/test/run-pass/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/foreign/auxiliary/foreign_lib.rs deleted file mode 100644 index de6b0e2118a..00000000000 --- a/src/test/run-pass/foreign/auxiliary/foreign_lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![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/src/test/run-pass/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/foreign/foreign-call-no-runtime.rs deleted file mode 100644 index c6afa07ad05..00000000000 --- a/src/test/run-pass/foreign/foreign-call-no-runtime.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-dupe.rs b/src/test/run-pass/foreign/foreign-dupe.rs deleted file mode 100644 index 3c9f0f583d4..00000000000 --- a/src/test/run-pass/foreign/foreign-dupe.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-fn-linkname.rs b/src/test/run-pass/foreign/foreign-fn-linkname.rs deleted file mode 100644 index 1f048159064..00000000000 --- a/src/test/run-pass/foreign/foreign-fn-linkname.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-fn-with-byval.rs b/src/test/run-pass/foreign/foreign-fn-with-byval.rs deleted file mode 100644 index 3a35599aa57..00000000000 --- a/src/test/run-pass/foreign/foreign-fn-with-byval.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-int-types.rs b/src/test/run-pass/foreign/foreign-int-types.rs deleted file mode 100644 index 66296574d7d..00000000000 --- a/src/test/run-pass/foreign/foreign-int-types.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-mod-src/compiletest-ignore-dir b/src/test/run-pass/foreign/foreign-mod-src/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/foreign/foreign-mod-src/inner.rs b/src/test/run-pass/foreign/foreign-mod-src/inner.rs deleted file mode 100644 index cf484878b07..00000000000 --- a/src/test/run-pass/foreign/foreign-mod-src/inner.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-mod-unused-const.rs b/src/test/run-pass/foreign/foreign-mod-unused-const.rs deleted file mode 100644 index d9efbe00e52..00000000000 --- a/src/test/run-pass/foreign/foreign-mod-unused-const.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -mod foo { - extern { - pub static errno: u32; - } -} - -pub fn main() { -} diff --git a/src/test/run-pass/foreign/foreign-no-abi.rs b/src/test/run-pass/foreign/foreign-no-abi.rs deleted file mode 100644 index 2f33fb47656..00000000000 --- a/src/test/run-pass/foreign/foreign-no-abi.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-src/compiletest-ignore-dir b/src/test/run-pass/foreign/foreign-src/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/foreign/foreign-src/foreign.rs b/src/test/run-pass/foreign/foreign-src/foreign.rs deleted file mode 100644 index 47016ad6ce7..00000000000 --- a/src/test/run-pass/foreign/foreign-src/foreign.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign-truncated-arguments.rs b/src/test/run-pass/foreign/foreign-truncated-arguments.rs deleted file mode 100644 index c61c2b587b6..00000000000 --- a/src/test/run-pass/foreign/foreign-truncated-arguments.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/foreign/foreign2.rs b/src/test/run-pass/foreign/foreign2.rs deleted file mode 100644 index c1ab57776f6..00000000000 --- a/src/test/run-pass/foreign/foreign2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/format-hygiene.rs b/src/test/run-pass/format-hygiene.rs deleted file mode 100644 index 6bf5ae8bead..00000000000 --- a/src/test/run-pass/format-hygiene.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![allow(non_upper_case_globals)] -pub const arg0: u8 = 1; - -pub fn main() { - format!("{}", 1); -} diff --git a/src/test/run-pass/format-nan.rs b/src/test/run-pass/format-nan.rs deleted file mode 100644 index e4a134fa2fb..00000000000 --- a/src/test/run-pass/format-nan.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -pub fn main() { - use std::f64; - let x = "NaN".to_string(); - assert_eq!(format!("{}", f64::NAN), x); - assert_eq!(format!("{:e}", f64::NAN), x); - assert_eq!(format!("{:E}", f64::NAN), x); -} diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs deleted file mode 100644 index c9b7651bfda..00000000000 --- a/src/test/run-pass/format-no-std.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/format-ref-cell.rs b/src/test/run-pass/format-ref-cell.rs deleted file mode 100644 index afb2f8488b8..00000000000 --- a/src/test/run-pass/format-ref-cell.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -use std::cell::RefCell; - -pub fn main() { - let name = RefCell::new("rust"); - let what = RefCell::new("rocks"); - let msg = format!("{name} {}", &*what.borrow(), name=&*name.borrow()); - assert_eq!(msg, "rust rocks".to_string()); -} diff --git a/src/test/run-pass/fsu-moves-and-copies.rs b/src/test/run-pass/fsu-moves-and-copies.rs deleted file mode 100644 index c41bcc73fa5..00000000000 --- a/src/test/run-pass/fsu-moves-and-copies.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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/src/test/run-pass/fun-call-variants.rs b/src/test/run-pass/fun-call-variants.rs deleted file mode 100644 index 5b83e2620d8..00000000000 --- a/src/test/run-pass/fun-call-variants.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/fun-indirect-call.rs b/src/test/run-pass/fun-indirect-call.rs deleted file mode 100644 index 49da3d83f4a..00000000000 --- a/src/test/run-pass/fun-indirect-call.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/functions-closures/auxiliary/fn-abi.rs b/src/test/run-pass/functions-closures/auxiliary/fn-abi.rs deleted file mode 100644 index 25c9e1b4ca3..00000000000 --- a/src/test/run-pass/functions-closures/auxiliary/fn-abi.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[no_mangle] -pub extern fn foo() {} diff --git a/src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs b/src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs deleted file mode 100644 index 8e1c68fd77d..00000000000 --- a/src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs b/src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs deleted file mode 100644 index bcde504635d..00000000000 --- a/src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs b/src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs deleted file mode 100644 index 206b3d7b613..00000000000 --- a/src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/functions-closures/clone-closure.rs b/src/test/run-pass/functions-closures/clone-closure.rs deleted file mode 100644 index 1e725d8056d..00000000000 --- a/src/test/run-pass/functions-closures/clone-closure.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs b/src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs deleted file mode 100644 index ccb2e201d7d..00000000000 --- a/src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-expected-type/README.md b/src/test/run-pass/functions-closures/closure-expected-type/README.md deleted file mode 100644 index fd493e1ff37..00000000000 --- a/src/test/run-pass/functions-closures/closure-expected-type/README.md +++ /dev/null @@ -1,8 +0,0 @@ -Some tests targeted at how we deduce the types of closure arguments. -This process is a result of some heuristics aimed at combining the -*expected type* we have with the *actual types* that we get from -inputs. This investigation was kicked off by #38714, which revealed -some pretty deep flaws in the ad-hoc way that we were doing things -before. - -See also `src/test/compile-fail/closure-expected-type`. diff --git a/src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs b/src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs deleted file mode 100644 index 6d5a9876c37..00000000000 --- a/src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs b/src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs deleted file mode 100644 index e97785b5cac..00000000000 --- a/src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs b/src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs deleted file mode 100644 index e9964531c3c..00000000000 --- a/src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs b/src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs deleted file mode 100644 index 8665cfc21a7..00000000000 --- a/src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-immediate.rs b/src/test/run-pass/functions-closures/closure-immediate.rs deleted file mode 100644 index 428fc6bdef3..00000000000 --- a/src/test/run-pass/functions-closures/closure-immediate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-inference.rs b/src/test/run-pass/functions-closures/closure-inference.rs deleted file mode 100644 index 96878445245..00000000000 --- a/src/test/run-pass/functions-closures/closure-inference.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - - -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/src/test/run-pass/functions-closures/closure-inference2.rs b/src/test/run-pass/functions-closures/closure-inference2.rs deleted file mode 100644 index f2dfa5888aa..00000000000 --- a/src/test/run-pass/functions-closures/closure-inference2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// Test a rather underspecified example: - - -pub fn main() { - let f = {|i| i}; - assert_eq!(f(2), 2); - assert_eq!(f(5), 5); -} diff --git a/src/test/run-pass/functions-closures/closure-reform.rs b/src/test/run-pass/functions-closures/closure-reform.rs deleted file mode 100644 index 0bb6159ff4a..00000000000 --- a/src/test/run-pass/functions-closures/closure-reform.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure-returning-closure.rs b/src/test/run-pass/functions-closures/closure-returning-closure.rs deleted file mode 100644 index 17db81687ab..00000000000 --- a/src/test/run-pass/functions-closures/closure-returning-closure.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -fn main() { - let f = |_||x, y| x+y; - assert_eq!(f(())(1, 2), 3); -} diff --git a/src/test/run-pass/functions-closures/closure-to-fn-coercion.rs b/src/test/run-pass/functions-closures/closure-to-fn-coercion.rs deleted file mode 100644 index 4f43c2bb538..00000000000 --- a/src/test/run-pass/functions-closures/closure-to-fn-coercion.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs b/src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs deleted file mode 100644 index e7a9383950f..00000000000 --- a/src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/functions-closures/copy-closure.rs b/src/test/run-pass/functions-closures/copy-closure.rs deleted file mode 100644 index 72da02421b7..00000000000 --- a/src/test/run-pass/functions-closures/copy-closure.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-abi.rs b/src/test/run-pass/functions-closures/fn-abi.rs deleted file mode 100644 index 900af9c1f66..00000000000 --- a/src/test/run-pass/functions-closures/fn-abi.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-bare-assign.rs b/src/test/run-pass/functions-closures/fn-bare-assign.rs deleted file mode 100644 index f5dab3c8402..00000000000 --- a/src/test/run-pass/functions-closures/fn-bare-assign.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs b/src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs deleted file mode 100644 index 922e016ddc8..00000000000 --- a/src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-bare-item.rs b/src/test/run-pass/functions-closures/fn-bare-item.rs deleted file mode 100644 index a6e6495a40a..00000000000 --- a/src/test/run-pass/functions-closures/fn-bare-item.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -fn f() { - println!("This is a bare function"); -} - -pub fn main() { - f(); -} diff --git a/src/test/run-pass/functions-closures/fn-bare-size.rs b/src/test/run-pass/functions-closures/fn-bare-size.rs deleted file mode 100644 index 2ba56eaaed4..00000000000 --- a/src/test/run-pass/functions-closures/fn-bare-size.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-bare-spawn.rs b/src/test/run-pass/functions-closures/fn-bare-spawn.rs deleted file mode 100644 index 0d46fe22087..00000000000 --- a/src/test/run-pass/functions-closures/fn-bare-spawn.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-coerce-field.rs b/src/test/run-pass/functions-closures/fn-coerce-field.rs deleted file mode 100644 index 38bde7b9e8f..00000000000 --- a/src/test/run-pass/functions-closures/fn-coerce-field.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-item-type-cast.rs b/src/test/run-pass/functions-closures/fn-item-type-cast.rs deleted file mode 100644 index 4d50ea97b8b..00000000000 --- a/src/test/run-pass/functions-closures/fn-item-type-cast.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-item-type-coerce.rs b/src/test/run-pass/functions-closures/fn-item-type-coerce.rs deleted file mode 100644 index 7a096764e45..00000000000 --- a/src/test/run-pass/functions-closures/fn-item-type-coerce.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs b/src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs deleted file mode 100644 index bd9f1ed663d..00000000000 --- a/src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-lval.rs b/src/test/run-pass/functions-closures/fn-lval.rs deleted file mode 100644 index 01079eea457..00000000000 --- a/src/test/run-pass/functions-closures/fn-lval.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/functions-closures/fn-type-infer.rs b/src/test/run-pass/functions-closures/fn-type-infer.rs deleted file mode 100644 index fe6567f22b5..00000000000 --- a/src/test/run-pass/functions-closures/fn-type-infer.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs b/src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs deleted file mode 100644 index 4ac07123d9d..00000000000 --- a/src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs b/src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs deleted file mode 100644 index 87dacfba25b..00000000000 --- a/src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/functions-closures/parallel-codegen-closures.rs b/src/test/run-pass/functions-closures/parallel-codegen-closures.rs deleted file mode 100644 index 79759daba50..00000000000 --- a/src/test/run-pass/functions-closures/parallel-codegen-closures.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/functions-closures/return-from-closure.rs b/src/test/run-pass/functions-closures/return-from-closure.rs deleted file mode 100644 index 656a95f120a..00000000000 --- a/src/test/run-pass/functions-closures/return-from-closure.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/generator/addassign-yield.rs b/src/test/run-pass/generator/addassign-yield.rs deleted file mode 100644 index 66f22bf31fc..00000000000 --- a/src/test/run-pass/generator/addassign-yield.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs b/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs deleted file mode 100644 index 33337f8038f..00000000000 --- a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![feature(generators, generator_trait)] - -use std::ops::Generator; - -fn msg() -> u32 { - 0 -} - -pub fn foo() -> impl Generator { - || { - yield; - return msg(); - } -} diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs deleted file mode 100644 index 613c495832f..00000000000 --- a/src/test/run-pass/generator/auxiliary/xcrate.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(generators, generator_trait)] - -use std::marker::Unpin; -use std::ops::Generator; - -pub fn foo() -> impl Generator { - || { - if false { - yield; - } - } -} - -pub fn bar(t: T) -> Box + Unpin> { - Box::new(|| { - yield t; - }) -} diff --git a/src/test/run-pass/generator/borrow-in-tail-expr.rs b/src/test/run-pass/generator/borrow-in-tail-expr.rs deleted file mode 100644 index 540f5e3e1dd..00000000000 --- a/src/test/run-pass/generator/borrow-in-tail-expr.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -#![feature(generators)] - -fn main() { - let _a = || { - yield; - let a = String::new(); - a.len() - }; -} diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs deleted file mode 100644 index 907f7a3c06d..00000000000 --- a/src/test/run-pass/generator/conditional-drop.rs +++ /dev/null @@ -1,58 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs deleted file mode 100644 index df70e013bd3..00000000000 --- a/src/test/run-pass/generator/control-flow.rs +++ /dev/null @@ -1,50 +0,0 @@ -// run-pass - -#![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 + 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/src/test/run-pass/generator/drop-and-replace.rs b/src/test/run-pass/generator/drop-and-replace.rs deleted file mode 100644 index bb33502815b..00000000000 --- a/src/test/run-pass/generator/drop-and-replace.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs deleted file mode 100644 index ac4e0665628..00000000000 --- a/src/test/run-pass/generator/drop-env.rs +++ /dev/null @@ -1,63 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs deleted file mode 100644 index 6efaff50c1e..00000000000 --- a/src/test/run-pass/generator/issue-44197.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 { - move || { - yield foo(&baz); - } -} - -fn foo2(_: &str) -> Result { - Err(()) -} - -fn bar2(baz: String) -> impl Generator { - 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/src/test/run-pass/generator/issue-52398.rs b/src/test/run-pass/generator/issue-52398.rs deleted file mode 100644 index 54a1912582c..00000000000 --- a/src/test/run-pass/generator/issue-52398.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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 || { - 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 || { - yield *y.borrow(); - return "Done"; - }; -} diff --git a/src/test/run-pass/generator/issue-57084.rs b/src/test/run-pass/generator/issue-57084.rs deleted file mode 100644 index 8aaa6a0e427..00000000000 --- a/src/test/run-pass/generator/issue-57084.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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]; - || { - let _to_pin = with(move || println!("{:p}", data)); - loop { - yield - } - }; -} diff --git a/src/test/run-pass/generator/issue-58888.rs b/src/test/run-pass/generator/issue-58888.rs deleted file mode 100644 index 43b37a9afc2..00000000000 --- a/src/test/run-pass/generator/issue-58888.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// compile-flags: -g - -#![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/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs deleted file mode 100644 index ac7e122dd58..00000000000 --- a/src/test/run-pass/generator/iterator-count.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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 + 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/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs deleted file mode 100644 index a1064165b2f..00000000000 --- a/src/test/run-pass/generator/live-upvar-across-yield.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/generator/match-bindings.rs b/src/test/run-pass/generator/match-bindings.rs deleted file mode 100644 index 560d8e7103c..00000000000 --- a/src/test/run-pass/generator/match-bindings.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -#![allow(dead_code)] - -#![feature(generators)] - -enum Enum { - A(String), - B -} - -fn main() { - || { - loop { - if let true = true { - match Enum::A(String::new()) { - Enum::A(_var) => {} - Enum::B => {} - } - } - yield; - } - }; -} diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs deleted file mode 100644 index b56cce1dc44..00000000000 --- a/src/test/run-pass/generator/nested_generators.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/generator/non-static-is-unpin.rs b/src/test/run-pass/generator/non-static-is-unpin.rs deleted file mode 100644 index 96d0a8e2833..00000000000 --- a/src/test/run-pass/generator/non-static-is-unpin.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/generator/overlap-locals.rs b/src/test/run-pass/generator/overlap-locals.rs deleted file mode 100644 index 101c8714fa8..00000000000 --- a/src/test/run-pass/generator/overlap-locals.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs deleted file mode 100644 index 5ac97585f4b..00000000000 --- a/src/test/run-pass/generator/panic-drops.rs +++ /dev/null @@ -1,57 +0,0 @@ -// run-pass - -// ignore-wasm32-bare compiled as 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/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs deleted file mode 100644 index 5f6778674dc..00000000000 --- a/src/test/run-pass/generator/panic-safe.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/generator/pin-box-generator.rs b/src/test/run-pass/generator/pin-box-generator.rs deleted file mode 100644 index c3136f5c0ec..00000000000 --- a/src/test/run-pass/generator/pin-box-generator.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/generator/reborrow-mut-upvar.rs b/src/test/run-pass/generator/reborrow-mut-upvar.rs deleted file mode 100644 index 785e38a7eb8..00000000000 --- a/src/test/run-pass/generator/reborrow-mut-upvar.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - -#![feature(generators)] - -fn _run(bar: &mut i32) { - || { - { - let _baz = &*bar; - yield; - } - - *bar = 2; - }; -} - -fn main() {} diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs deleted file mode 100644 index 71a68ff684a..00000000000 --- a/src/test/run-pass/generator/resume-after-return.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/generator/size-moved-locals.rs b/src/test/run-pass/generator/size-moved-locals.rs deleted file mode 100644 index 01db971434b..00000000000 --- a/src/test/run-pass/generator/size-moved-locals.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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 - -#![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!(1028, std::mem::size_of_val(&move_before_yield())); - assert_eq!(1032, std::mem::size_of_val(&move_before_yield_with_noop())); - assert_eq!(2056, std::mem::size_of_val(&overlap_move_points())); - assert_eq!(1032, std::mem::size_of_val(&overlap_x_and_y())); -} diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs deleted file mode 100644 index 533f2399084..00000000000 --- a/src/test/run-pass/generator/smoke.rs +++ /dev/null @@ -1,174 +0,0 @@ -// run-pass - -// 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/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs deleted file mode 100644 index 965d3c61c22..00000000000 --- a/src/test/run-pass/generator/static-generators.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs b/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs deleted file mode 100644 index f299a8aa72b..00000000000 --- a/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(unused_unsafe)] - -#![feature(generators)] - -fn main() { - unsafe { - static move || { - // 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/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs deleted file mode 100644 index 9483ad7395e..00000000000 --- a/src/test/run-pass/generator/xcrate-reachable.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/generator/xcrate.rs b/src/test/run-pass/generator/xcrate.rs deleted file mode 100644 index febf5c3583f..00000000000 --- a/src/test/run-pass/generator/xcrate.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/generator/yield-in-args-rev.rs b/src/test/run-pass/generator/yield-in-args-rev.rs deleted file mode 100644 index f9ab981121a..00000000000 --- a/src/test/run-pass/generator/yield-in-args-rev.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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() { - || { - let b = true; - foo(yield, &b); - }; -} - -fn main() { } diff --git a/src/test/run-pass/generator/yield-in-box.rs b/src/test/run-pass/generator/yield-in-box.rs deleted file mode 100644 index d8475715c7c..00000000000 --- a/src/test/run-pass/generator/yield-in-box.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass - -// Test that box-statements with yields in them work. - -#![feature(generators, box_syntax)] - -fn main() { - let x = 0i32; - || { - let y = 2u32; - { - let _t = box (&x, yield 0, &y); - } - match box (&x, yield 0, &y) { - _t => {} - } - }; -} diff --git a/src/test/run-pass/generator/yield-in-initializer.rs b/src/test/run-pass/generator/yield-in-initializer.rs deleted file mode 100644 index 8ff35d8ddf1..00000000000 --- a/src/test/run-pass/generator/yield-in-initializer.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -#![feature(generators)] - -fn main() { - static || { - 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/src/test/run-pass/generator/yield-subtype.rs b/src/test/run-pass/generator/yield-subtype.rs deleted file mode 100644 index fe88d424dd1..00000000000 --- a/src/test/run-pass/generator/yield-subtype.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(dead_code)] - -#![feature(generators)] - -fn bar<'a>() { - let a: &'static str = "hi"; - let b: &'a str = a; - - || { - yield a; - yield b; - }; -} - -fn main() {} diff --git a/src/test/run-pass/generics/auxiliary/default_type_params_xc.rs b/src/test/run-pass/generics/auxiliary/default_type_params_xc.rs deleted file mode 100644 index aacbd672ade..00000000000 --- a/src/test/run-pass/generics/auxiliary/default_type_params_xc.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub struct Heap; - -pub struct FakeHeap; - -pub struct FakeVec { pub f: Option<(T,A)> } diff --git a/src/test/run-pass/generics/generic-alias-unique.rs b/src/test/run-pass/generics/generic-alias-unique.rs deleted file mode 100644 index 76a184d8d25..00000000000 --- a/src/test/run-pass/generics/generic-alias-unique.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/generics/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generics/generic-default-type-params-cross-crate.rs deleted file mode 100644 index 9e5eaa72c15..00000000000 --- a/src/test/run-pass/generics/generic-default-type-params-cross-crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/generics/generic-default-type-params.rs b/src/test/run-pass/generics/generic-default-type-params.rs deleted file mode 100644 index afdd301fde9..00000000000 --- a/src/test/run-pass/generics/generic-default-type-params.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/generics/generic-derived-type.rs b/src/test/run-pass/generics/generic-derived-type.rs deleted file mode 100644 index c643496fa7f..00000000000 --- a/src/test/run-pass/generics/generic-derived-type.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/generics/generic-exterior-unique.rs b/src/test/run-pass/generics/generic-exterior-unique.rs deleted file mode 100644 index 9b3e1ee02a2..00000000000 --- a/src/test/run-pass/generics/generic-exterior-unique.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/generics/generic-extern-mangle.rs b/src/test/run-pass/generics/generic-extern-mangle.rs deleted file mode 100644 index 985a6f39cd7..00000000000 --- a/src/test/run-pass/generics/generic-extern-mangle.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/generics/generic-fn-infer.rs b/src/test/run-pass/generics/generic-fn-infer.rs deleted file mode 100644 index 9ba4224732b..00000000000 --- a/src/test/run-pass/generics/generic-fn-infer.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/generics/generic-fn-twice.rs b/src/test/run-pass/generics/generic-fn-twice.rs deleted file mode 100644 index 2f25fc24ced..00000000000 --- a/src/test/run-pass/generics/generic-fn-twice.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - - - -// pretty-expanded FIXME #23616 - -mod foomod { - pub fn foo() { } -} - -pub fn main() { foomod::foo::(); foomod::foo::(); } diff --git a/src/test/run-pass/generics/generic-fn-unique.rs b/src/test/run-pass/generics/generic-fn-unique.rs deleted file mode 100644 index 6cda1c3dc15..00000000000 --- a/src/test/run-pass/generics/generic-fn-unique.rs +++ /dev/null @@ -1,6 +0,0 @@ -// 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/src/test/run-pass/generics/generic-fn.rs b/src/test/run-pass/generics/generic-fn.rs deleted file mode 100644 index 8038fabc1ce..00000000000 --- a/src/test/run-pass/generics/generic-fn.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/generics/generic-ivec-leak.rs b/src/test/run-pass/generics/generic-ivec-leak.rs deleted file mode 100644 index a8ea1d5069b..00000000000 --- a/src/test/run-pass/generics/generic-ivec-leak.rs +++ /dev/null @@ -1,5 +0,0 @@ -// 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/src/test/run-pass/generics/generic-newtype-struct.rs b/src/test/run-pass/generics/generic-newtype-struct.rs deleted file mode 100644 index 570c982cc87..00000000000 --- a/src/test/run-pass/generics/generic-newtype-struct.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -struct S(T); - -pub fn main() { - let _s = S(2); -} diff --git a/src/test/run-pass/generics/generic-object.rs b/src/test/run-pass/generics/generic-object.rs deleted file mode 100644 index 870ff980ec6..00000000000 --- a/src/test/run-pass/generics/generic-object.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/generics/generic-recursive-tag.rs b/src/test/run-pass/generics/generic-recursive-tag.rs deleted file mode 100644 index e1875f0abbe..00000000000 --- a/src/test/run-pass/generics/generic-recursive-tag.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/generics/generic-static-methods.rs b/src/test/run-pass/generics/generic-static-methods.rs deleted file mode 100644 index b39fa081a65..00000000000 --- a/src/test/run-pass/generics/generic-static-methods.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tag-corruption.rs b/src/test/run-pass/generics/generic-tag-corruption.rs deleted file mode 100644 index aa26183a0d4..00000000000 --- a/src/test/run-pass/generics/generic-tag-corruption.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tag-local.rs b/src/test/run-pass/generics/generic-tag-local.rs deleted file mode 100644 index cc85e6e0f0a..00000000000 --- a/src/test/run-pass/generics/generic-tag-local.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tag-match.rs b/src/test/run-pass/generics/generic-tag-match.rs deleted file mode 100644 index 09ed6a808e6..00000000000 --- a/src/test/run-pass/generics/generic-tag-match.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tag-values.rs b/src/test/run-pass/generics/generic-tag-values.rs deleted file mode 100644 index 230f477b6e9..00000000000 --- a/src/test/run-pass/generics/generic-tag-values.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tag.rs b/src/test/run-pass/generics/generic-tag.rs deleted file mode 100644 index 74ef4eeba8a..00000000000 --- a/src/test/run-pass/generics/generic-tag.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/generics/generic-temporary.rs b/src/test/run-pass/generics/generic-temporary.rs deleted file mode 100644 index b63b534d03f..00000000000 --- a/src/test/run-pass/generics/generic-temporary.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/generics/generic-tup.rs b/src/test/run-pass/generics/generic-tup.rs deleted file mode 100644 index 79ebd648cd4..00000000000 --- a/src/test/run-pass/generics/generic-tup.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/generics/generic-type-synonym.rs b/src/test/run-pass/generics/generic-type-synonym.rs deleted file mode 100644 index 4f181fbcc7e..00000000000 --- a/src/test/run-pass/generics/generic-type-synonym.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/generics/generic-type.rs b/src/test/run-pass/generics/generic-type.rs deleted file mode 100644 index aa46db07eee..00000000000 --- a/src/test/run-pass/generics/generic-type.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/generics/generic-unique.rs b/src/test/run-pass/generics/generic-unique.rs deleted file mode 100644 index d36504c75dd..00000000000 --- a/src/test/run-pass/generics/generic-unique.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/global-scope.rs b/src/test/run-pass/global-scope.rs deleted file mode 100644 index 944eee5afc3..00000000000 --- a/src/test/run-pass/global-scope.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/guards-not-exhaustive.rs b/src/test/run-pass/guards-not-exhaustive.rs deleted file mode 100644 index b74f162c0c6..00000000000 --- a/src/test/run-pass/guards-not-exhaustive.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/guards.rs b/src/test/run-pass/guards.rs deleted file mode 100644 index 10a4bb67387..00000000000 --- a/src/test/run-pass/guards.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs deleted file mode 100644 index 3129eb0da82..00000000000 --- a/src/test/run-pass/hashmap-memory.rs +++ /dev/null @@ -1,94 +0,0 @@ -// 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/src/test/run-pass/hello.rs b/src/test/run-pass/hello.rs deleted file mode 100644 index c207c25545e..00000000000 --- a/src/test/run-pass/hello.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -pub fn main() { - println!("hello, world"); -} diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs deleted file mode 100644 index cc766c0605c..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs deleted file mode 100644 index 8431226a3ec..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs deleted file mode 100644 index ff84ad9d298..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs deleted file mode 100644 index afab9986ce2..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs deleted file mode 100644 index 04519f11600..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs deleted file mode 100644 index 1fab9758c5c..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs deleted file mode 100644 index 42247798f66..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs deleted file mode 100644 index 6834c392d4e..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs deleted file mode 100644 index b97fdf4df50..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs deleted file mode 100644 index d8c726cdd71..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs deleted file mode 100644 index 41ebb3f5a14..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs deleted file mode 100644 index a8f38180cc2..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs deleted file mode 100644 index a4a8a5ac6cc..00000000000 --- a/src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/html-literals.rs b/src/test/run-pass/html-literals.rs deleted file mode 100644 index ae45e97c8b0..00000000000 --- a/src/test/run-pass/html-literals.rs +++ /dev/null @@ -1,94 +0,0 @@ -// 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/src/test/run-pass/if-bot.rs b/src/test/run-pass/if-bot.rs deleted file mode 100644 index 0f09db530d4..00000000000 --- a/src/test/run-pass/if-bot.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -pub fn main() { - let i: isize = if false { panic!() } else { 5 }; - println!("{}", i); -} diff --git a/src/test/run-pass/if-check.rs b/src/test/run-pass/if-check.rs deleted file mode 100644 index 6593225e7dd..00000000000 --- a/src/test/run-pass/if-check.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/if-ret.rs b/src/test/run-pass/if-ret.rs deleted file mode 100644 index e1e795d83be..00000000000 --- a/src/test/run-pass/if-ret.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![allow(unused_parens)] -// pretty-expanded FIXME #23616 - -fn foo() { if (return) { } } - -pub fn main() { foo(); } diff --git a/src/test/run-pass/if-ret.stderr b/src/test/run-pass/if-ret.stderr deleted file mode 100644 index 73402e55a4f..00000000000 --- a/src/test/run-pass/if-ret.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: unreachable block in `if` expression - --> $DIR/if-ret.rs:6:24 - | -LL | fn foo() { if (return) { } } - | ^^^ - | - = note: `#[warn(unreachable_code)]` on by default - diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs deleted file mode 100644 index 841be20ef86..00000000000 --- a/src/test/run-pass/ifmt.rs +++ /dev/null @@ -1,323 +0,0 @@ -// run-pass - -#![deny(warnings)] -#![allow(unused_must_use)] -#![allow(unused_features)] -#![feature(box_syntax)] - -use std::cell::RefCell; -use std::fmt::{self, Write}; -use std::usize; - -struct A; -struct B; -struct C; -struct D; - -impl fmt::LowerHex for A { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("aloha") - } -} -impl fmt::UpperHex for B { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("adios") - } -} -impl fmt::Display for C { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad_integral(true, "☃", "123") - } -} -impl fmt::Binary for D { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("aa")?; - f.write_char('☃')?; - f.write_str("bb") - } -} - -macro_rules! t { - ($a:expr, $b:expr) => { assert_eq!($a, $b) } -} - -pub fn main() { - // Various edge cases without formats - t!(format!(""), ""); - t!(format!("hello"), "hello"); - t!(format!("hello {{"), "hello {"); - - // default formatters should work - t!(format!("{}", 1.0f32), "1"); - t!(format!("{}", 1.0f64), "1"); - t!(format!("{}", "a"), "a"); - t!(format!("{}", "a".to_string()), "a"); - t!(format!("{}", false), "false"); - t!(format!("{}", 'a'), "a"); - - // At least exercise all the formats - t!(format!("{}", true), "true"); - t!(format!("{}", '☃'), "☃"); - t!(format!("{}", 10), "10"); - t!(format!("{}", 10_usize), "10"); - t!(format!("{:?}", '☃'), "'☃'"); - t!(format!("{:?}", 10), "10"); - t!(format!("{:?}", 10_usize), "10"); - t!(format!("{:?}", "true"), "\"true\""); - t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\""); - t!(format!("{:?}", "foo\n\"bar\"\r\n\'baz\'\t\\qux\\"), - r#""foo\n\"bar\"\r\n\'baz\'\t\\qux\\""#); - t!(format!("{:?}", "foo\0bar\x01baz\u{7f}q\u{75}x"), - r#""foo\u{0}bar\u{1}baz\u{7f}qux""#); - t!(format!("{:o}", 10_usize), "12"); - t!(format!("{:x}", 10_usize), "a"); - t!(format!("{:X}", 10_usize), "A"); - t!(format!("{}", "foo"), "foo"); - t!(format!("{}", "foo".to_string()), "foo"); - if cfg!(target_pointer_width = "32") { - t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234"); - t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234"); - } else { - t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234"); - t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234"); - } - t!(format!("{:p}", 0x1234 as *const isize), "0x1234"); - t!(format!("{:p}", 0x1234 as *mut isize), "0x1234"); - t!(format!("{:x}", A), "aloha"); - t!(format!("{:X}", B), "adios"); - t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃"); - t!(format!("{1} {0}", 0, 1), "1 0"); - t!(format!("{foo} {bar}", foo=0, bar=1), "0 1"); - t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0"); - t!(format!("{} {0}", "a"), "a a"); - t!(format!("{foo_bar}", foo_bar=1), "1"); - t!(format!("{}", 5 + 5), "10"); - t!(format!("{:#4}", C), "☃123"); - t!(format!("{:b}", D), "aa☃bb"); - - let a: &dyn fmt::Debug = &1; - t!(format!("{:?}", a), "1"); - - - // Formatting strings and their arguments - t!(format!("{}", "a"), "a"); - t!(format!("{:4}", "a"), "a "); - t!(format!("{:4}", "☃"), "☃ "); - t!(format!("{:>4}", "a"), " a"); - t!(format!("{:<4}", "a"), "a "); - t!(format!("{:^5}", "a"), " a "); - t!(format!("{:^5}", "aa"), " aa "); - t!(format!("{:^4}", "a"), " a "); - t!(format!("{:^4}", "aa"), " aa "); - t!(format!("{:.4}", "a"), "a"); - t!(format!("{:4.4}", "a"), "a "); - t!(format!("{:4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); - t!(format!("{:<4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); - t!(format!("{:>4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); - t!(format!("{:^4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); - t!(format!("{:>10.4}", "aaaaaaaaaaaaaaaaaa"), " aaaa"); - t!(format!("{:2.4}", "aaaaa"), "aaaa"); - t!(format!("{:2.4}", "aaaa"), "aaaa"); - t!(format!("{:2.4}", "aaa"), "aaa"); - t!(format!("{:2.4}", "aa"), "aa"); - t!(format!("{:2.4}", "a"), "a "); - t!(format!("{:0>2}", "a"), "0a"); - t!(format!("{:.*}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa"); - t!(format!("{:.1$}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa"); - t!(format!("{:.a$}", "aaaaaaaaaaaaaaaaaa", a=4), "aaaa"); - t!(format!("{:1$}", "a", 4), "a "); - t!(format!("{1:0$}", 4, "a"), "a "); - t!(format!("{:a$}", "a", a=4), "a "); - t!(format!("{:-#}", "a"), "a"); - t!(format!("{:+#}", "a"), "a"); - t!(format!("{:/^10.8}", "1234567890"), "/12345678/"); - - // Some float stuff - t!(format!("{:}", 1.0f32), "1"); - t!(format!("{:}", 1.0f64), "1"); - t!(format!("{:.3}", 1.0f64), "1.000"); - t!(format!("{:10.3}", 1.0f64), " 1.000"); - t!(format!("{:+10.3}", 1.0f64), " +1.000"); - t!(format!("{:+10.3}", -1.0f64), " -1.000"); - - t!(format!("{:e}", 1.2345e6f32), "1.2345e6"); - t!(format!("{:e}", 1.2345e6f64), "1.2345e6"); - t!(format!("{:E}", 1.2345e6f64), "1.2345E6"); - t!(format!("{:.3e}", 1.2345e6f64), "1.234e6"); - t!(format!("{:10.3e}", 1.2345e6f64), " 1.234e6"); - t!(format!("{:+10.3e}", 1.2345e6f64), " +1.234e6"); - t!(format!("{:+10.3e}", -1.2345e6f64), " -1.234e6"); - - // Float edge cases - t!(format!("{}", -0.0), "0"); - t!(format!("{:?}", -0.0), "-0.0"); - t!(format!("{:?}", 0.0), "0.0"); - - // sign aware zero padding - t!(format!("{:<3}", 1), "1 "); - t!(format!("{:>3}", 1), " 1"); - t!(format!("{:^3}", 1), " 1 "); - t!(format!("{:03}", 1), "001"); - t!(format!("{:<03}", 1), "001"); - t!(format!("{:>03}", 1), "001"); - t!(format!("{:^03}", 1), "001"); - t!(format!("{:+03}", 1), "+01"); - t!(format!("{:<+03}", 1), "+01"); - t!(format!("{:>+03}", 1), "+01"); - t!(format!("{:^+03}", 1), "+01"); - t!(format!("{:#05x}", 1), "0x001"); - t!(format!("{:<#05x}", 1), "0x001"); - t!(format!("{:>#05x}", 1), "0x001"); - t!(format!("{:^#05x}", 1), "0x001"); - t!(format!("{:05}", 1.2), "001.2"); - t!(format!("{:<05}", 1.2), "001.2"); - t!(format!("{:>05}", 1.2), "001.2"); - t!(format!("{:^05}", 1.2), "001.2"); - t!(format!("{:05}", -1.2), "-01.2"); - t!(format!("{:<05}", -1.2), "-01.2"); - t!(format!("{:>05}", -1.2), "-01.2"); - t!(format!("{:^05}", -1.2), "-01.2"); - t!(format!("{:+05}", 1.2), "+01.2"); - t!(format!("{:<+05}", 1.2), "+01.2"); - t!(format!("{:>+05}", 1.2), "+01.2"); - t!(format!("{:^+05}", 1.2), "+01.2"); - - // Ergonomic format_args! - t!(format!("{0:x} {0:X}", 15), "f F"); - t!(format!("{0:x} {0:X} {}", 15), "f F 15"); - // NOTE: For now the longer test cases must not be followed immediately by - // >1 empty lines, or the pretty printer will break. Since no one wants to - // touch the current pretty printer (#751), we have no choice but to work - // around it. Some of the following test cases are also affected. - t!(format!("{:x}{0:X}{a:x}{:X}{1:x}{a:X}", 13, 14, a=15), "dDfEeF"); - t!(format!("{a:x} {a:X}", a=15), "f F"); - - // And its edge cases - t!(format!("{a:.0$} {b:.0$} {0:.0$}\n{a:.c$} {b:.c$} {c:.c$}", - 4, a="abcdefg", b="hijklmn", c=3), - "abcd hijk 4\nabc hij 3"); - t!(format!("{a:.*} {0} {:.*}", 4, 3, "efgh", a="abcdef"), "abcd 4 efg"); - t!(format!("{:.a$} {a} {a:#x}", "aaaaaa", a=2), "aa 2 0x2"); - - - // Test that pointers don't get truncated. - { - let val = usize::MAX; - let exp = format!("{:#x}", val); - t!(format!("{:p}", val as *const isize), exp); - } - - // Escaping - t!(format!("{{"), "{"); - t!(format!("}}"), "}"); - - test_write(); - test_print(); - test_order(); - test_once(); - - // make sure that format! doesn't move out of local variables - let a: Box<_> = box 3; - format!("{}", a); - format!("{}", a); - - // make sure that format! doesn't cause spurious unused-unsafe warnings when - // it's inside of an outer unsafe block - unsafe { - let a: isize = ::std::mem::transmute(3_usize); - format!("{}", a); - } - - test_format_args(); - - // test that trailing commas are acceptable - format!("{}", "test",); - format!("{foo}", foo="test",); - - test_refcell(); -} - -// Basic test to make sure that we can invoke the `write!` macro with an -// fmt::Write instance. -fn test_write() { - let mut buf = String::new(); - write!(&mut buf, "{}", 3); - { - let w = &mut buf; - write!(w, "{foo}", foo=4); - write!(w, "{}", "hello"); - writeln!(w, "{}", "line"); - writeln!(w, "{foo}", foo="bar"); - w.write_char('☃'); - w.write_str("str"); - } - - t!(buf, "34helloline\nbar\n☃str"); -} - -// Just make sure that the macros are defined, there's not really a lot that we -// can do with them just yet (to test the output) -fn test_print() { - print!("hi"); - print!("{:?}", vec![0u8]); - println!("hello"); - println!("this is a {}", "test"); - println!("{foo}", foo="bar"); -} - -// Just make sure that the macros are defined, there's not really a lot that we -// can do with them just yet (to test the output) -fn test_format_args() { - let mut buf = String::new(); - { - let w = &mut buf; - write!(w, "{}", format_args!("{}", 1)); - write!(w, "{}", format_args!("test")); - write!(w, "{}", format_args!("{test}", test=3)); - } - let s = buf; - t!(s, "1test3"); - - let s = fmt::format(format_args!("hello {}", "world")); - t!(s, "hello world"); - let s = format!("{}: {}", "args were", format_args!("hello {}", "world")); - t!(s, "args were: hello world"); -} - -fn test_order() { - // Make sure format!() arguments are always evaluated in a left-to-right - // ordering - fn foo() -> isize { - static mut FOO: isize = 0; - unsafe { - FOO += 1; - FOO - } - } - assert_eq!(format!("{} {} {a} {b} {} {c}", - foo(), foo(), foo(), a=foo(), b=foo(), c=foo()), - "1 2 4 5 3 6".to_string()); -} - -fn test_once() { - // Make sure each argument are evaluated only once even though it may be - // formatted multiple times - fn foo() -> isize { - static mut FOO: isize = 0; - unsafe { - FOO += 1; - FOO - } - } - assert_eq!(format!("{0} {0} {0} {a} {a} {a}", foo(), a=foo()), - "1 1 1 2 2 2".to_string()); -} - -fn test_refcell() { - let refcell = RefCell::new(5); - assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }"); - let borrow = refcell.borrow_mut(); - assert_eq!(format!("{:?}", refcell), "RefCell { value: }"); - drop(borrow); - assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }"); -} diff --git a/src/test/run-pass/ignore-all-the-things.rs b/src/test/run-pass/ignore-all-the-things.rs deleted file mode 100644 index 8c046a289fa..00000000000 --- a/src/test/run-pass/ignore-all-the-things.rs +++ /dev/null @@ -1,47 +0,0 @@ -// run-pass - -#![allow(non_shorthand_field_patterns)] -#![allow(dead_code)] -#![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -#![feature(slice_patterns)] - -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/src/test/run-pass/impl-for-never.rs b/src/test/run-pass/impl-for-never.rs deleted file mode 100644 index c5f12981ecc..00000000000 --- a/src/test/run-pass/impl-for-never.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -// Test that we can call static methods on ! both directly and when it appears in a generic - -#![feature(never_type)] - -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/src/test/run-pass/impl-inherent-non-conflict.rs b/src/test/run-pass/impl-inherent-non-conflict.rs deleted file mode 100644 index be524f87c9f..00000000000 --- a/src/test/run-pass/impl-inherent-non-conflict.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/impl-not-adjacent-to-type.rs b/src/test/run-pass/impl-not-adjacent-to-type.rs deleted file mode 100644 index 97caf908387..00000000000 --- a/src/test/run-pass/impl-not-adjacent-to-type.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/impl-privacy-xc-1.rs b/src/test/run-pass/impl-privacy-xc-1.rs deleted file mode 100644 index c9f7f09c7bd..00000000000 --- a/src/test/run-pass/impl-privacy-xc-1.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/impl-privacy-xc-2.rs b/src/test/run-pass/impl-privacy-xc-2.rs deleted file mode 100644 index 390764588fc..00000000000 --- a/src/test/run-pass/impl-privacy-xc-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/impl-trait-in-bindings.rs b/src/test/run-pass/impl-trait-in-bindings.rs deleted file mode 100644 index 2e9b6cd5c78..00000000000 --- a/src/test/run-pass/impl-trait-in-bindings.rs +++ /dev/null @@ -1,49 +0,0 @@ -// run-pass - -#![feature(impl_trait_in_bindings)] -//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - -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/src/test/run-pass/impl-trait-in-bindings.stderr b/src/test/run-pass/impl-trait-in-bindings.stderr deleted file mode 100644 index 54b42a102fa..00000000000 --- a/src/test/run-pass/impl-trait-in-bindings.stderr +++ /dev/null @@ -1,6 +0,0 @@ -warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/impl-trait-in-bindings.rs:3:12 - | -LL | #![feature(impl_trait_in_bindings)] - | ^^^^^^^^^^^^^^^^^^^^^^ - diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs deleted file mode 100644 index ac016258b7f..00000000000 --- a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/impl-trait/bounds_regression.rs b/src/test/run-pass/impl-trait/bounds_regression.rs deleted file mode 100644 index 0fdeb6bdee1..00000000000 --- a/src/test/run-pass/impl-trait/bounds_regression.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs deleted file mode 100644 index f1b1656745e..00000000000 --- a/src/test/run-pass/impl-trait/example-calendar.rs +++ /dev/null @@ -1,857 +0,0 @@ -// run-pass - -#![feature(fn_traits, - step_trait, - unboxed_closures, -)] - -//! Derived from: . -//! -//! Originally converted to Rust by [Daniel Keep](https://github.com/DanielKeep). - -use std::fmt::Write; -use std::mem; - -/// 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() - } -} - -impl std::iter::Step for NaiveDate { - fn steps_between(_: &Self, _: &Self) -> Option { - unimplemented!() - } - - fn replace_one(&mut self) -> Self { - mem::replace(self, NaiveDate(0, 0, 1)) - } - - fn replace_zero(&mut self) -> Self { - mem::replace(self, NaiveDate(0, 0, 0)) - } - - fn add_one(&self) -> Self { - self.succ() - } - - fn sub_one(&self) -> Self { - unimplemented!() - } - - fn add_usize(&self, _: usize) -> Option { - unimplemented!() - } - - fn sub_usize(&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/src/test/run-pass/impl-trait/example-st.rs b/src/test/run-pass/impl-trait/example-st.rs deleted file mode 100644 index 4e1aa3a0859..00000000000 --- a/src/test/run-pass/impl-trait/example-st.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs deleted file mode 100644 index 9a9843375e4..00000000000 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ /dev/null @@ -1,123 +0,0 @@ -// 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/src/test/run-pass/impl-trait/nesting.rs b/src/test/run-pass/impl-trait/nesting.rs deleted file mode 100644 index 27bdd5fa483..00000000000 --- a/src/test/run-pass/impl-trait/nesting.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_hrtb_anon.rs b/src/test/run-pass/impl-trait/universal_hrtb_anon.rs deleted file mode 100644 index 30c8d291f6a..00000000000 --- a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_hrtb_named.rs b/src/test/run-pass/impl-trait/universal_hrtb_named.rs deleted file mode 100644 index 07ff5d23e0c..00000000000 --- a/src/test/run-pass/impl-trait/universal_hrtb_named.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs deleted file mode 100644 index a3829133dfa..00000000000 --- a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs deleted file mode 100644 index e98912d95a5..00000000000 --- a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs deleted file mode 100644 index 23c217a8f8b..00000000000 --- a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/impl-trait/universal_multiple_bounds.rs b/src/test/run-pass/impl-trait/universal_multiple_bounds.rs deleted file mode 100644 index 40c1405c39b..00000000000 --- a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/impl-trait/xcrate.rs b/src/test/run-pass/impl-trait/xcrate.rs deleted file mode 100644 index b73d2946c2b..00000000000 --- a/src/test/run-pass/impl-trait/xcrate.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/impl-trait/xcrate_simple.rs b/src/test/run-pass/impl-trait/xcrate_simple.rs deleted file mode 100644 index 2b1fc97e321..00000000000 --- a/src/test/run-pass/impl-trait/xcrate_simple.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -// aux-build:xcrate.rs - -extern crate xcrate; - -fn main() { - xcrate::return_internal_fn()(); -} diff --git a/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs b/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs deleted file mode 100644 index b76c1680bba..00000000000 --- a/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![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/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs deleted file mode 100644 index 63611c24299..00000000000 --- a/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs +++ /dev/null @@ -1,7 +0,0 @@ -macro_rules! add1 { - ($e:expr) => ({ - let a = 1 + $e; - let b = $e + 1; - a + b - 1 - }) -} diff --git a/src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs b/src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs deleted file mode 100644 index 64a4deca8c3..00000000000 --- a/src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/imports/import-from.rs b/src/test/run-pass/imports/import-from.rs deleted file mode 100644 index 2817977b393..00000000000 --- a/src/test/run-pass/imports/import-from.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/imports/import-glob-1.rs b/src/test/run-pass/imports/import-glob-1.rs deleted file mode 100644 index fcc0b63f101..00000000000 --- a/src/test/run-pass/imports/import-glob-1.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/imports/import-glob-crate.rs b/src/test/run-pass/imports/import-glob-crate.rs deleted file mode 100644 index 501392b7829..00000000000 --- a/src/test/run-pass/imports/import-glob-crate.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/imports/import-in-block.rs b/src/test/run-pass/imports/import-in-block.rs deleted file mode 100644 index c0ba6220b54..00000000000 --- a/src/test/run-pass/imports/import-in-block.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - use std::mem::replace; - let mut x = 5; - replace(&mut x, 6); - { - use std::mem::*; - let mut y = 6; - swap(&mut x, &mut y); - } -} diff --git a/src/test/run-pass/imports/import-prefix-macro.rs b/src/test/run-pass/imports/import-prefix-macro.rs deleted file mode 100644 index d770bb0da80..00000000000 --- a/src/test/run-pass/imports/import-prefix-macro.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/imports/import-rename.rs b/src/test/run-pass/imports/import-rename.rs deleted file mode 100644 index 9ad2b34b837..00000000000 --- a/src/test/run-pass/imports/import-rename.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/imports/import-trailing-comma.rs b/src/test/run-pass/imports/import-trailing-comma.rs deleted file mode 100644 index f65c5c866a3..00000000000 --- a/src/test/run-pass/imports/import-trailing-comma.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/imports/import.rs b/src/test/run-pass/imports/import.rs deleted file mode 100644 index de8bf626114..00000000000 --- a/src/test/run-pass/imports/import.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/imports/import2.rs b/src/test/run-pass/imports/import2.rs deleted file mode 100644 index 7b70f799ebf..00000000000 --- a/src/test/run-pass/imports/import2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -use zed::bar; - -mod zed { - pub fn bar() { println!("bar"); } -} - -pub fn main() { bar(); } diff --git a/src/test/run-pass/imports/import3.rs b/src/test/run-pass/imports/import3.rs deleted file mode 100644 index 17797aed359..00000000000 --- a/src/test/run-pass/imports/import3.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/imports/import4.rs b/src/test/run-pass/imports/import4.rs deleted file mode 100644 index 4fda5386112..00000000000 --- a/src/test/run-pass/imports/import4.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -use zed::bar; - -mod zed { - pub fn bar() { println!("bar"); } -} - -pub fn main() { let _zed = 42; bar(); } diff --git a/src/test/run-pass/imports/import5.rs b/src/test/run-pass/imports/import5.rs deleted file mode 100644 index be2a55c2d41..00000000000 --- a/src/test/run-pass/imports/import5.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/imports/import6.rs b/src/test/run-pass/imports/import6.rs deleted file mode 100644 index e11b28531f9..00000000000 --- a/src/test/run-pass/imports/import6.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/imports/import7.rs b/src/test/run-pass/imports/import7.rs deleted file mode 100644 index aca7fbdc4f5..00000000000 --- a/src/test/run-pass/imports/import7.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/imports/import8.rs b/src/test/run-pass/imports/import8.rs deleted file mode 100644 index 87f0986bae4..00000000000 --- a/src/test/run-pass/imports/import8.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/imports/imports.rs b/src/test/run-pass/imports/imports.rs deleted file mode 100644 index acb2b32b59d..00000000000 --- a/src/test/run-pass/imports/imports.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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/src/test/run-pass/in-band-lifetimes.rs b/src/test/run-pass/in-band-lifetimes.rs deleted file mode 100644 index c9f7d28699e..00000000000 --- a/src/test/run-pass/in-band-lifetimes.rs +++ /dev/null @@ -1,96 +0,0 @@ -// 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 existential_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { - x -} -fn existential_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { - x -} -fn existential_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { - x -} -fn existential_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { - x -} -fn existential_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { - x -} - -fn main() {} diff --git a/src/test/run-pass/inc-range-pat.rs b/src/test/run-pass/inc-range-pat.rs deleted file mode 100644 index 1eb7dd0aa3e..00000000000 --- a/src/test/run-pass/inc-range-pat.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/infer-fn-tail-expr.rs b/src/test/run-pass/infer-fn-tail-expr.rs deleted file mode 100644 index 413b1877a29..00000000000 --- a/src/test/run-pass/infer-fn-tail-expr.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -#![allow(dead_code)] -// issue #680 - - -// pretty-expanded FIXME #23616 - -fn f() -> Vec { Vec::new() } - -pub fn main() { } diff --git a/src/test/run-pass/inherit-env.rs b/src/test/run-pass/inherit-env.rs deleted file mode 100644 index e29fa04bbd5..00000000000 --- a/src/test/run-pass/inherit-env.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/init-large-type.rs b/src/test/run-pass/init-large-type.rs deleted file mode 100644 index a304fc9356b..00000000000 --- a/src/test/run-pass/init-large-type.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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::thread; - -extern "rust-intrinsic" { - pub fn init() -> T; -} - -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 { init() }; - }).join(); -} diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs deleted file mode 100644 index ed0c600c1d2..00000000000 --- a/src/test/run-pass/init-res-into-things.rs +++ /dev/null @@ -1,82 +0,0 @@ -// 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/src/test/run-pass/inlined-main.rs b/src/test/run-pass/inlined-main.rs deleted file mode 100644 index 75ff4c87dc6..00000000000 --- a/src/test/run-pass/inlined-main.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass - -#[inline(always)] -fn main() {} diff --git a/src/test/run-pass/inner-attrs-on-impl.rs b/src/test/run-pass/inner-attrs-on-impl.rs deleted file mode 100644 index 636e8c4885e..00000000000 --- a/src/test/run-pass/inner-attrs-on-impl.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/inner-module.rs b/src/test/run-pass/inner-module.rs deleted file mode 100644 index 363f753e248..00000000000 --- a/src/test/run-pass/inner-module.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs deleted file mode 100644 index adba299ebe2..00000000000 --- a/src/test/run-pass/inner-static.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/instantiable.rs b/src/test/run-pass/instantiable.rs deleted file mode 100644 index ad0cf3f4ac9..00000000000 --- a/src/test/run-pass/instantiable.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs b/src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs deleted file mode 100644 index f65f359875b..00000000000 --- a/src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![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/src/test/run-pass/intrinsics/intrinsic-alignment.rs b/src/test/run-pass/intrinsics/intrinsic-alignment.rs deleted file mode 100644 index 6a67d04a54c..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-alignment.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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"))] -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] - #[cfg(target_arch = "x86")] - pub fn main() { - unsafe { - assert_eq!(::rusti::pref_align_of::(), 8); - assert_eq!(::rusti::min_align_of::(), 8); - } - } - - #[main] - #[cfg(target_arch = "x86_64")] - pub fn main() { - unsafe { - assert_eq!(::rusti::pref_align_of::(), 8); - assert_eq!(::rusti::min_align_of::(), 8); - } - } -} diff --git a/src/test/run-pass/intrinsics/intrinsic-assume.rs b/src/test/run-pass/intrinsics/intrinsic-assume.rs deleted file mode 100644 index 3c9d70cb556..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-assume.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs b/src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs deleted file mode 100644 index 52e891da9ba..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/intrinsics/intrinsic-atomics.rs b/src/test/run-pass/intrinsics/intrinsic-atomics.rs deleted file mode 100644 index 608cf3dee52..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-atomics.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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/src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs b/src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs deleted file mode 100644 index a2068429af5..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs +++ /dev/null @@ -1,190 +0,0 @@ -// run-pass -#![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/src/test/run-pass/intrinsics/intrinsic-move-val.rs b/src/test/run-pass/intrinsics/intrinsic-move-val.rs deleted file mode 100644 index 75b4ec365fe..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-move-val.rs +++ /dev/null @@ -1,82 +0,0 @@ -// run-pass - -#![feature(box_syntax)] -#![feature(intrinsics)] - -mod rusti { - extern "rust-intrinsic" { - pub fn init() -> T; - pub fn move_val_init(dst: *mut T, src: T); - } -} - -pub fn main() { - unsafe { - // sanity check - check_drops_state(0, None); - - let mut x: Box = box D(1); - assert_eq!(x.0, 1); - - // A normal overwrite, to demonstrate `check_drops_state`. - x = 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: Box = rusti::init(); - - // 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.0, 2); - y.0 = 3; - assert_eq!(y.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/src/test/run-pass/intrinsics/intrinsic-unreachable.rs b/src/test/run-pass/intrinsics/intrinsic-unreachable.rs deleted file mode 100644 index da1a32d58ea..00000000000 --- a/src/test/run-pass/intrinsics/intrinsic-unreachable.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/intrinsics/intrinsics-integer.rs b/src/test/run-pass/intrinsics/intrinsics-integer.rs deleted file mode 100644 index 0154f049950..00000000000 --- a/src/test/run-pass/intrinsics/intrinsics-integer.rs +++ /dev/null @@ -1,172 +0,0 @@ -// run-pass -// ignore-emscripten no i128 support - -#![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/src/test/run-pass/intrinsics/intrinsics-math.rs b/src/test/run-pass/intrinsics/intrinsics-math.rs deleted file mode 100644 index aea9fde6915..00000000000 --- a/src/test/run-pass/intrinsics/intrinsics-math.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/invalid_const_promotion.rs b/src/test/run-pass/invalid_const_promotion.rs deleted file mode 100644 index 6d59bb385dc..00000000000 --- a/src/test/run-pass/invalid_const_promotion.rs +++ /dev/null @@ -1,56 +0,0 @@ -// run-pass - -#![allow(unused_mut)] -// ignore-wasm32 -// ignore-emscripten -// ignore-sgx no processes - -// compile-flags: -C debug_assertions=yes - -#![stable(feature = "rustc", since = "1.0.0")] -#![feature(const_fn, rustc_private, staged_api, rustc_attrs)] -#![allow(const_err)] - -extern crate libc; - -use std::env; -use std::process::{Command, Stdio}; - -// this will panic in debug mode and overflow in release mode -#[stable(feature = "rustc", since = "1.0.0")] -#[rustc_promotable] -const fn bar() -> usize { 0 - 1 } - -fn foo() { - let _: &'static _ = &bar(); -} - -#[cfg(unix)] -fn check_status(status: std::process::ExitStatus) -{ - use std::os::unix::process::ExitStatusExt; - - assert!(status.signal() == Some(libc::SIGILL) - || status.signal() == Some(libc::SIGTRAP) - || 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] == "test" { - foo(); - return; - } - - let mut p = Command::new(&args[0]) - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .arg("test").output().unwrap(); - check_status(p.status); -} diff --git a/src/test/run-pass/invoke-external-foreign.rs b/src/test/run-pass/invoke-external-foreign.rs deleted file mode 100644 index dbd2b4ad865..00000000000 --- a/src/test/run-pass/invoke-external-foreign.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/irrefutable-unit.rs b/src/test/run-pass/irrefutable-unit.rs deleted file mode 100644 index dd8f03b6dbd..00000000000 --- a/src/test/run-pass/irrefutable-unit.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - let ((),()) = ((),()); -} diff --git a/src/test/run-pass/issue-59020.rs b/src/test/run-pass/issue-59020.rs deleted file mode 100644 index e7544934da0..00000000000 --- a/src/test/run-pass/issue-59020.rs +++ /dev/null @@ -1,28 +0,0 @@ -// edition:2018 -// run-pass -// ignore-emscripten no threads support -// ignore-sgx no thread sleep 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/src/test/run-pass/issues/.gitattributes b/src/test/run-pass/issues/.gitattributes deleted file mode 100644 index 4517a4a2f1e..00000000000 --- a/src/test/run-pass/issues/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -issue-16278.rs -text diff --git a/src/test/run-pass/issues/auxiliary/cgu_test.rs b/src/test/run-pass/issues/auxiliary/cgu_test.rs deleted file mode 100644 index 5ed973164a1..00000000000 --- a/src/test/run-pass/issues/auxiliary/cgu_test.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic -// compile-flags: --crate-type=lib - -pub fn id(t: T) -> T { - t -} diff --git a/src/test/run-pass/issues/auxiliary/cgu_test_a.rs b/src/test/run-pass/issues/auxiliary/cgu_test_a.rs deleted file mode 100644 index a3dcd92012e..00000000000 --- a/src/test/run-pass/issues/auxiliary/cgu_test_a.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/auxiliary/cgu_test_b.rs b/src/test/run-pass/issues/auxiliary/cgu_test_b.rs deleted file mode 100644 index a3dcd92012e..00000000000 --- a/src/test/run-pass/issues/auxiliary/cgu_test_b.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/auxiliary/i8.rs b/src/test/run-pass/issues/auxiliary/i8.rs deleted file mode 100644 index 889a9c4ebb1..00000000000 --- a/src/test/run-pass/issues/auxiliary/i8.rs +++ /dev/null @@ -1,3 +0,0 @@ -// A crate named after a built-in type. - -pub struct Test; diff --git a/src/test/run-pass/issues/auxiliary/iss.rs b/src/test/run-pass/issues/auxiliary/iss.rs deleted file mode 100644 index cf32f6c2d5d..00000000000 --- a/src/test/run-pass/issues/auxiliary/iss.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-10028.rs b/src/test/run-pass/issues/auxiliary/issue-10028.rs deleted file mode 100644 index 135f26f4047..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-10028.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct ZeroLengthThingWithDestructor; -impl Drop for ZeroLengthThingWithDestructor { - fn drop(&mut self) {} -} -impl ZeroLengthThingWithDestructor { - pub fn new() -> ZeroLengthThingWithDestructor { - ZeroLengthThingWithDestructor - } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs b/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs deleted file mode 100644 index e2abeb99ea8..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct Wrap(pub A); diff --git a/src/test/run-pass/issues/auxiliary/issue-11224.rs b/src/test/run-pass/issues/auxiliary/issue-11224.rs deleted file mode 100644 index 63543621a80..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11224.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-11225-1.rs b/src/test/run-pass/issues/auxiliary/issue-11225-1.rs deleted file mode 100644 index 2c6f899a0f4..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11225-1.rs +++ /dev/null @@ -1,18 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-11225-2.rs b/src/test/run-pass/issues/auxiliary/issue-11225-2.rs deleted file mode 100644 index 4381f0a4edf..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11225-2.rs +++ /dev/null @@ -1,28 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-11225-3.rs b/src/test/run-pass/issues/auxiliary/issue-11225-3.rs deleted file mode 100644 index 266e42a10b5..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11225-3.rs +++ /dev/null @@ -1,28 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-11508.rs b/src/test/run-pass/issues/auxiliary/issue-11508.rs deleted file mode 100644 index 16bfc65c2b5..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11508.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-11529.rs b/src/test/run-pass/issues/auxiliary/issue-11529.rs deleted file mode 100644 index dd3ef438705..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-11529.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct A<'a>(pub &'a isize); diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs b/src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs deleted file mode 100644 index 8bd2b3353b8..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs +++ /dev/null @@ -1 +0,0 @@ -#![crate_type = "dylib"] diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs b/src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs deleted file mode 100644 index 30de7400600..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "dylib"] - -extern crate issue_12133_rlib as a; -extern crate issue_12133_dylib as b; diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs b/src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs deleted file mode 100644 index 39c261e1162..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs +++ /dev/null @@ -1,3 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] diff --git a/src/test/run-pass/issues/auxiliary/issue-12612-1.rs b/src/test/run-pass/issues/auxiliary/issue-12612-1.rs deleted file mode 100644 index 01f5a784bb7..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12612-1.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod bar { - pub fn foo() {} -} diff --git a/src/test/run-pass/issues/auxiliary/issue-12612-2.rs b/src/test/run-pass/issues/auxiliary/issue-12612-2.rs deleted file mode 100644 index 2c724787193..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12612-2.rs +++ /dev/null @@ -1 +0,0 @@ -pub fn baz() {} diff --git a/src/test/run-pass/issues/auxiliary/issue-12660-aux.rs b/src/test/run-pass/issues/auxiliary/issue-12660-aux.rs deleted file mode 100644 index 6dea8662dfe..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-12660-aux.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-13507.rs b/src/test/run-pass/issues/auxiliary/issue-13507.rs deleted file mode 100644 index c91013043eb..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13507.rs +++ /dev/null @@ -1,87 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-13620-1.rs b/src/test/run-pass/issues/auxiliary/issue-13620-1.rs deleted file mode 100644 index 1442c0cc7aa..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13620-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct Foo { - pub foo: extern fn() -} - -extern fn the_foo() {} - -pub const FOO: Foo = Foo { - foo: the_foo -}; diff --git a/src/test/run-pass/issues/auxiliary/issue-13620-2.rs b/src/test/run-pass/issues/auxiliary/issue-13620-2.rs deleted file mode 100644 index 7efd24407ba..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13620-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate issue_13620_1 as crate1; - -pub static FOO2: crate1::Foo = crate1::FOO; diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-1.rs b/src/test/run-pass/issues/auxiliary/issue-13872-1.rs deleted file mode 100644 index fa9258834c7..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13872-1.rs +++ /dev/null @@ -1 +0,0 @@ -pub enum A { B } diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-2.rs b/src/test/run-pass/issues/auxiliary/issue-13872-2.rs deleted file mode 100644 index 8c64f16e3f9..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13872-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate issue_13872_1 as foo; - -pub use foo::A::B; diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-3.rs b/src/test/run-pass/issues/auxiliary/issue-13872-3.rs deleted file mode 100644 index d31d52eb847..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-13872-3.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate issue_13872_2 as bar; - -use bar::B; - -pub fn foo() { - match B { - B => {} - } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-14344-1.rs b/src/test/run-pass/issues/auxiliary/issue-14344-1.rs deleted file mode 100644 index 954a1e554da..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-14344-1.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -pub fn foo() {} diff --git a/src/test/run-pass/issues/auxiliary/issue-14344-2.rs b/src/test/run-pass/issues/auxiliary/issue-14344-2.rs deleted file mode 100644 index c47b8c0ea6c..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-14344-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate issue_14344_1; - -pub fn bar() {} diff --git a/src/test/run-pass/issues/auxiliary/issue-14421.rs b/src/test/run-pass/issues/auxiliary/issue-14421.rs deleted file mode 100644 index 5fe4b24cf17..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-14421.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-14422.rs b/src/test/run-pass/issues/auxiliary/issue-14422.rs deleted file mode 100644 index a6026c1d03f..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-14422.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-15562.rs b/src/test/run-pass/issues/auxiliary/issue-15562.rs deleted file mode 100644 index d5afaaa5622..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-15562.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type = "lib"] - -extern { - pub fn transmute(); -} diff --git a/src/test/run-pass/issues/auxiliary/issue-16643.rs b/src/test/run-pass/issues/auxiliary/issue-16643.rs deleted file mode 100644 index 7808e0119f6..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-16643.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-17662.rs b/src/test/run-pass/issues/auxiliary/issue-17662.rs deleted file mode 100644 index 75efe110cdf..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-17662.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs b/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs deleted file mode 100644 index 91abdbff868..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-18501.rs b/src/test/run-pass/issues/auxiliary/issue-18501.rs deleted file mode 100644 index dd914b464fa..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-18501.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-18514.rs b/src/test/run-pass/issues/auxiliary/issue-18514.rs deleted file mode 100644 index 20c8e60ee45..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-18514.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-18711.rs b/src/test/run-pass/issues/auxiliary/issue-18711.rs deleted file mode 100644 index 5cb1f9c4371..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-18711.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type = "rlib"] - -pub fn inner(f: F) -> F { - (move || f)() -} diff --git a/src/test/run-pass/issues/auxiliary/issue-18913-1.rs b/src/test/run-pass/issues/auxiliary/issue-18913-1.rs deleted file mode 100644 index 053c5ada5ee..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-18913-1.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] -#![crate_name = "foo"] - -pub fn foo() -> i32 { 0 } diff --git a/src/test/run-pass/issues/auxiliary/issue-18913-2.rs b/src/test/run-pass/issues/auxiliary/issue-18913-2.rs deleted file mode 100644 index 54747b45f52..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-18913-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] -#![crate_name = "foo"] - -pub fn foo() -> i32 { 1 } diff --git a/src/test/run-pass/issues/auxiliary/issue-19293.rs b/src/test/run-pass/issues/auxiliary/issue-19293.rs deleted file mode 100644 index 31359e86559..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-19293.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub struct Foo (pub isize); -pub enum MyEnum { - Foo(Foo), -} diff --git a/src/test/run-pass/issues/auxiliary/issue-19340-1.rs b/src/test/run-pass/issues/auxiliary/issue-19340-1.rs deleted file mode 100644 index 39ee36b8b91..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-19340-1.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub enum Homura { - Madoka { name: String }, -} diff --git a/src/test/run-pass/issues/auxiliary/issue-20389.rs b/src/test/run-pass/issues/auxiliary/issue-20389.rs deleted file mode 100644 index ae6d44eeb77..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-20389.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub trait T { - type C; - fn dummy(&self) { } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs b/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs deleted file mode 100644 index a99385a834d..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-2316-a.rs b/src/test/run-pass/issues/auxiliary/issue-2316-a.rs deleted file mode 100644 index 418ddc0b069..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2316-a.rs +++ /dev/null @@ -1,3 +0,0 @@ -enum cat { - tabby, calico, tortoiseshell -} diff --git a/src/test/run-pass/issues/auxiliary/issue-2316-b.rs b/src/test/run-pass/issues/auxiliary/issue-2316-b.rs deleted file mode 100644 index 550c2d6eb22..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2316-b.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![allow(unused_imports)] - -extern crate issue_2316_a; - -pub mod cloth { - use issue_2316_a::*; - - pub enum fabric { - gingham, flannel, calico - } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-2380.rs b/src/test/run-pass/issues/auxiliary/issue-2380.rs deleted file mode 100644 index 9a51a73c9a3..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2380.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-2414-a.rs b/src/test/run-pass/issues/auxiliary/issue-2414-a.rs deleted file mode 100644 index b90ab32ddc4..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2414-a.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![crate_name="a"] -#![crate_type = "lib"] - -type t1 = usize; - -trait foo { - fn foo(&self); -} - -impl foo for String { - fn foo(&self) {} -} diff --git a/src/test/run-pass/issues/auxiliary/issue-2414-b.rs b/src/test/run-pass/issues/auxiliary/issue-2414-b.rs deleted file mode 100644 index fc018349d80..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2414-b.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![crate_name="b"] -#![crate_type = "lib"] - -extern crate a; diff --git a/src/test/run-pass/issues/auxiliary/issue-2472-b.rs b/src/test/run-pass/issues/auxiliary/issue-2472-b.rs deleted file mode 100644 index 0d151520fe0..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2472-b.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-25185-1.rs b/src/test/run-pass/issues/auxiliary/issue-25185-1.rs deleted file mode 100644 index 77a4787ba94..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-25185-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/auxiliary/issue-25185-2.rs b/src/test/run-pass/issues/auxiliary/issue-25185-2.rs deleted file mode 100644 index 7ce3df255a3..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-25185-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate issue_25185_1; - -pub use issue_25185_1::rust_dbg_extern_identity_u32; diff --git a/src/test/run-pass/issues/auxiliary/issue-2526.rs b/src/test/run-pass/issues/auxiliary/issue-2526.rs deleted file mode 100644 index 3b27f658cda..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2526.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-25467.rs b/src/test/run-pass/issues/auxiliary/issue-25467.rs deleted file mode 100644 index ca9b3097c83..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-25467.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-2631-a.rs b/src/test/run-pass/issues/auxiliary/issue-2631-a.rs deleted file mode 100644 index 1e8211bfaa7..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2631-a.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-2723-a.rs b/src/test/run-pass/issues/auxiliary/issue-2723-a.rs deleted file mode 100644 index 661b46d829d..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-2723-a.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub unsafe fn f(xs: Vec ) { - xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::>(); -} diff --git a/src/test/run-pass/issues/auxiliary/issue-29485.rs b/src/test/run-pass/issues/auxiliary/issue-29485.rs deleted file mode 100644 index 1e8891c5120..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-29485.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-3012-1.rs b/src/test/run-pass/issues/auxiliary/issue-3012-1.rs deleted file mode 100644 index 509af2a8d7d..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-3012-1.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-3136-a.rc b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc deleted file mode 100644 index cd5fd314505..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-3136-a.rc +++ /dev/null @@ -1,4 +0,0 @@ -#![crate_type = "lib"] - -#[path = "issue-3136-a.rs"] -pub mod issue_3136_a; diff --git a/src/test/run-pass/issues/auxiliary/issue-3136-a.rs b/src/test/run-pass/issues/auxiliary/issue-3136-a.rs deleted file mode 100644 index 9bb546ab393..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-3136-a.rs +++ /dev/null @@ -1,14 +0,0 @@ -trait x { - fn use_x(&self); -} -struct y(()); -impl x for y { - fn use_x(&self) { - struct foo { //~ ERROR quux - i: () - } - fn new_foo(i: ()) -> foo { - foo { i: i } - } - } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-31702-1.rs b/src/test/run-pass/issues/auxiliary/issue-31702-1.rs deleted file mode 100644 index a48d0dc2c64..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-31702-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[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/src/test/run-pass/issues/auxiliary/issue-31702-2.rs b/src/test/run-pass/issues/auxiliary/issue-31702-2.rs deleted file mode 100644 index d360ae0ca7e..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-31702-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs b/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs deleted file mode 100644 index 09c69b90329..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-36954.rs b/src/test/run-pass/issues/auxiliary/issue-36954.rs deleted file mode 100644 index bc444a3817b..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-36954.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![crate_type = "lib"] - -const fn foo(i: i32) -> i32 { - i -} - -pub const FOO: i32 = foo(1); diff --git a/src/test/run-pass/issues/auxiliary/issue-38190.rs b/src/test/run-pass/issues/auxiliary/issue-38190.rs deleted file mode 100644 index 373e646ba2c..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-38190.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[macro_export] -macro_rules! m { ([$i:item]) => {} } diff --git a/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs b/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs deleted file mode 100644 index f968017199f..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs b/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs deleted file mode 100644 index 15d072957cb..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![allow(duplicate_macro_exports)] - -#[macro_export] -macro_rules! foo_modern { ($i:ident) => {} } - -#[macro_export] -macro_rules! foo_modern { () => {} } diff --git a/src/test/run-pass/issues/auxiliary/issue-38715.rs b/src/test/run-pass/issues/auxiliary/issue-38715.rs deleted file mode 100644 index 5c15073f5a5..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-38715.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![allow(duplicate_macro_exports)] - -#[macro_export] -macro_rules! foo { ($i:ident) => {} } - -#[macro_export] -macro_rules! foo { () => {} } diff --git a/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs b/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs deleted file mode 100644 index 5d03a0e9e99..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-39823.rs b/src/test/run-pass/issues/auxiliary/issue-39823.rs deleted file mode 100644 index 3af9c68f233..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-39823.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![crate_type="rlib"] - -#[derive(Debug, PartialEq)] -pub struct RemoteC(pub u32); - -#[derive(Debug, PartialEq)] -pub struct RemoteG(pub T); diff --git a/src/test/run-pass/issues/auxiliary/issue-40469.rs b/src/test/run-pass/issues/auxiliary/issue-40469.rs deleted file mode 100644 index 4f2f41f2cde..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-40469.rs +++ /dev/null @@ -1 +0,0 @@ -macro_rules! m { () => { $crate::main(); } } diff --git a/src/test/run-pass/issues/auxiliary/issue-41053.rs b/src/test/run-pass/issues/auxiliary/issue-41053.rs deleted file mode 100644 index ae73c3e780f..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-41053.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct Test; diff --git a/src/test/run-pass/issues/auxiliary/issue-41394.rs b/src/test/run-pass/issues/auxiliary/issue-41394.rs deleted file mode 100644 index 2e650efc714..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-41394.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-42007-s.rs b/src/test/run-pass/issues/auxiliary/issue-42007-s.rs deleted file mode 100644 index 95119a589c9..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-42007-s.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[repr(u8)] -pub enum E { - B = 1 as u8, -} diff --git a/src/test/run-pass/issues/auxiliary/issue-4208-cc.rs b/src/test/run-pass/issues/auxiliary/issue-4208-cc.rs deleted file mode 100644 index 7b4c8b01a9e..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-4208-cc.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![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/src/test/run-pass/issues/auxiliary/issue-4545.rs b/src/test/run-pass/issues/auxiliary/issue-4545.rs deleted file mode 100644 index 2f609475075..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-4545.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub struct S(Option); -pub fn mk() -> S { S(None) } diff --git a/src/test/run-pass/issues/auxiliary/issue-48984-aux.rs b/src/test/run-pass/issues/auxiliary/issue-48984-aux.rs deleted file mode 100644 index 7cc888cd4cb..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-48984-aux.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![crate_type = "lib"] -#![crate_name = "issue48984aux"] - -pub trait Foo { type Item; } - -pub trait Bar: Foo { } diff --git a/src/test/run-pass/issues/auxiliary/issue-5518.rs b/src/test/run-pass/issues/auxiliary/issue-5518.rs deleted file mode 100644 index bfe96552a5c..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-5518.rs +++ /dev/null @@ -1,4 +0,0 @@ -trait A<'a, T> { - fn f(&mut self) -> &'a mut T; - fn p() -> T; -} diff --git a/src/test/run-pass/issues/auxiliary/issue-5521.rs b/src/test/run-pass/issues/auxiliary/issue-5521.rs deleted file mode 100644 index c2f81779b35..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-5521.rs +++ /dev/null @@ -1,3 +0,0 @@ -use std::collections::HashMap; - -pub type map = Box>; diff --git a/src/test/run-pass/issues/auxiliary/issue-7178.rs b/src/test/run-pass/issues/auxiliary/issue-7178.rs deleted file mode 100644 index 56ae5139af4..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-7178.rs +++ /dev/null @@ -1,7 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-7899.rs b/src/test/run-pass/issues/auxiliary/issue-7899.rs deleted file mode 100644 index 3af6e871661..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-7899.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct V2(pub T, pub T); diff --git a/src/test/run-pass/issues/auxiliary/issue-8044.rs b/src/test/run-pass/issues/auxiliary/issue-8044.rs deleted file mode 100644 index 2ec25f51cde..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-8044.rs +++ /dev/null @@ -1,15 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-8259.rs b/src/test/run-pass/issues/auxiliary/issue-8259.rs deleted file mode 100644 index 891aee099dc..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-8259.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub enum Foo<'a> { - A, - B(&'a str), -} diff --git a/src/test/run-pass/issues/auxiliary/issue-8401.rs b/src/test/run-pass/issues/auxiliary/issue-8401.rs deleted file mode 100644 index e35dbbfabfc..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-8401.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/auxiliary/issue-9123.rs b/src/test/run-pass/issues/auxiliary/issue-9123.rs deleted file mode 100644 index 60af53359e8..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-9123.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_type = "lib"] - -pub trait X { - fn x() { - fn f() { } - f(); - } - fn dummy(&self) { } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-9155.rs b/src/test/run-pass/issues/auxiliary/issue-9155.rs deleted file mode 100644 index 049a96a655a..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-9155.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub struct Foo(T); - -impl Foo { - pub fn new(t: T) -> Foo { - Foo(t) - } -} diff --git a/src/test/run-pass/issues/auxiliary/issue-9188.rs b/src/test/run-pass/issues/auxiliary/issue-9188.rs deleted file mode 100644 index 3bc5697a1a6..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-9188.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-9906.rs b/src/test/run-pass/issues/auxiliary/issue-9906.rs deleted file mode 100644 index 8a3eea790a2..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-9906.rs +++ /dev/null @@ -1,15 +0,0 @@ -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/src/test/run-pass/issues/auxiliary/issue-9968.rs b/src/test/run-pass/issues/auxiliary/issue-9968.rs deleted file mode 100644 index 8d795b59ea8..00000000000 --- a/src/test/run-pass/issues/auxiliary/issue-9968.rs +++ /dev/null @@ -1,22 +0,0 @@ -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/src/test/run-pass/issues/issue-10025.rs b/src/test/run-pass/issues/issue-10025.rs deleted file mode 100644 index 193d7ee891f..00000000000 --- a/src/test/run-pass/issues/issue-10025.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10028.rs b/src/test/run-pass/issues/issue-10028.rs deleted file mode 100644 index 1692470e8d1..00000000000 --- a/src/test/run-pass/issues/issue-10028.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10031.rs b/src/test/run-pass/issues/issue-10031.rs deleted file mode 100644 index 136df05c239..00000000000 --- a/src/test/run-pass/issues/issue-10031.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10228.rs b/src/test/run-pass/issues/issue-10228.rs deleted file mode 100644 index ebf8b436f13..00000000000 --- a/src/test/run-pass/issues/issue-10228.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10392.rs b/src/test/run-pass/issues/issue-10392.rs deleted file mode 100644 index 926fa94800e..00000000000 --- a/src/test/run-pass/issues/issue-10392.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10436.rs b/src/test/run-pass/issues/issue-10436.rs deleted file mode 100644 index a7a20bad517..00000000000 --- a/src/test/run-pass/issues/issue-10436.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10626.rs b/src/test/run-pass/issues/issue-10626.rs deleted file mode 100644 index 78fa8b7c6fb..00000000000 --- a/src/test/run-pass/issues/issue-10626.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10638.rs b/src/test/run-pass/issues/issue-10638.rs deleted file mode 100644 index e359669c00d..00000000000 --- a/src/test/run-pass/issues/issue-10638.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10682.rs b/src/test/run-pass/issues/issue-10682.rs deleted file mode 100644 index afaa90f05ca..00000000000 --- a/src/test/run-pass/issues/issue-10682.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10683.rs b/src/test/run-pass/issues/issue-10683.rs deleted file mode 100644 index dcb221f8c57..00000000000 --- a/src/test/run-pass/issues/issue-10683.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -static NAME: &'static str = "hello world"; - -fn main() { - match &*NAME.to_ascii_lowercase() { - "foo" => {} - _ => {} - } -} diff --git a/src/test/run-pass/issues/issue-10718.rs b/src/test/run-pass/issues/issue-10718.rs deleted file mode 100644 index a1de0cfe6ca..00000000000 --- a/src/test/run-pass/issues/issue-10718.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn f(p: F) { - p(); -} - -pub fn main() { - let p = || (); - f(p); -} diff --git a/src/test/run-pass/issues/issue-10734.rs b/src/test/run-pass/issues/issue-10734.rs deleted file mode 100644 index 723e6ed22dd..00000000000 --- a/src/test/run-pass/issues/issue-10734.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10767.rs b/src/test/run-pass/issues/issue-10767.rs deleted file mode 100644 index fa10f073b45..00000000000 --- a/src/test/run-pass/issues/issue-10767.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(box_syntax)] - -pub fn main() { - fn f() { - }; - let _: Box = box (f as fn()); -} diff --git a/src/test/run-pass/issues/issue-10802.rs b/src/test/run-pass/issues/issue-10802.rs deleted file mode 100644 index f1d6b37a684..00000000000 --- a/src/test/run-pass/issues/issue-10802.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-10806.rs b/src/test/run-pass/issues/issue-10806.rs deleted file mode 100644 index 2f1d7bb5aaf..00000000000 --- a/src/test/run-pass/issues/issue-10806.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11047.rs b/src/test/run-pass/issues/issue-11047.rs deleted file mode 100644 index 1fb2b5bb3a1..00000000000 --- a/src/test/run-pass/issues/issue-11047.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11085.rs b/src/test/run-pass/issues/issue-11085.rs deleted file mode 100644 index 47c03238b55..00000000000 --- a/src/test/run-pass/issues/issue-11085.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1112.rs b/src/test/run-pass/issues/issue-1112.rs deleted file mode 100644 index 3ba7bb21708..00000000000 --- a/src/test/run-pass/issues/issue-1112.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11205.rs b/src/test/run-pass/issues/issue-11205.rs deleted file mode 100644 index ce0951eafdd..00000000000 --- a/src/test/run-pass/issues/issue-11205.rs +++ /dev/null @@ -1,85 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11224.rs b/src/test/run-pass/issues/issue-11224.rs deleted file mode 100644 index e1c1df99aca..00000000000 --- a/src/test/run-pass/issues/issue-11224.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-11224.rs - -// pretty-expanded FIXME #23616 - -extern crate issue_11224 as unused; - -pub fn main() {} diff --git a/src/test/run-pass/issues/issue-11225-1.rs b/src/test/run-pass/issues/issue-11225-1.rs deleted file mode 100644 index d1f2ea5e7de..00000000000 --- a/src/test/run-pass/issues/issue-11225-1.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11225-2.rs b/src/test/run-pass/issues/issue-11225-2.rs deleted file mode 100644 index d41c75443f1..00000000000 --- a/src/test/run-pass/issues/issue-11225-2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11225-3.rs b/src/test/run-pass/issues/issue-11225-3.rs deleted file mode 100644 index e69496baa26..00000000000 --- a/src/test/run-pass/issues/issue-11225-3.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11267.rs b/src/test/run-pass/issues/issue-11267.rs deleted file mode 100644 index 848ed6ac7a8..00000000000 --- a/src/test/run-pass/issues/issue-11267.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11382.rs b/src/test/run-pass/issues/issue-11382.rs deleted file mode 100644 index 42a7a0d04a1..00000000000 --- a/src/test/run-pass/issues/issue-11382.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - println!("{}", 1.2); -} diff --git a/src/test/run-pass/issues/issue-11508.rs b/src/test/run-pass/issues/issue-11508.rs deleted file mode 100644 index 49868b73efa..00000000000 --- a/src/test/run-pass/issues/issue-11508.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11529.rs b/src/test/run-pass/issues/issue-11529.rs deleted file mode 100644 index 9a6cc8e9fe8..00000000000 --- a/src/test/run-pass/issues/issue-11529.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11552.rs b/src/test/run-pass/issues/issue-11552.rs deleted file mode 100644 index bae12375da1..00000000000 --- a/src/test/run-pass/issues/issue-11552.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11577.rs b/src/test/run-pass/issues/issue-11577.rs deleted file mode 100644 index 70177c5ed0d..00000000000 --- a/src/test/run-pass/issues/issue-11577.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11677.rs b/src/test/run-pass/issues/issue-11677.rs deleted file mode 100644 index be18c736f14..00000000000 --- a/src/test/run-pass/issues/issue-11677.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11709.rs b/src/test/run-pass/issues/issue-11709.rs deleted file mode 100644 index cb5e3dff3b3..00000000000 --- a/src/test/run-pass/issues/issue-11709.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11820.rs b/src/test/run-pass/issues/issue-11820.rs deleted file mode 100644 index 7ffe9652797..00000000000 --- a/src/test/run-pass/issues/issue-11820.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-11940.rs b/src/test/run-pass/issues/issue-11940.rs deleted file mode 100644 index 6815c87edd8..00000000000 --- a/src/test/run-pass/issues/issue-11940.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -const TEST_STR: &'static str = "abcd"; - -fn main() { - let s = "abcd"; - match s { - TEST_STR => (), - _ => unreachable!() - } -} diff --git a/src/test/run-pass/issues/issue-11958.rs b/src/test/run-pass/issues/issue-11958.rs deleted file mode 100644 index 8fe8a8c6061..00000000000 --- a/src/test/run-pass/issues/issue-11958.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![forbid(warnings)] - -// 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; }); -} diff --git a/src/test/run-pass/issues/issue-12033.rs b/src/test/run-pass/issues/issue-12033.rs deleted file mode 100644 index 9dc7573c9d3..00000000000 --- a/src/test/run-pass/issues/issue-12033.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -use std::cell::RefCell; - -fn main() { - let x = RefCell::new(0); - if *x.borrow() == 0 {} else {} -} diff --git a/src/test/run-pass/issues/issue-12133-1.rs b/src/test/run-pass/issues/issue-12133-1.rs deleted file mode 100644 index 96ad5abd548..00000000000 --- a/src/test/run-pass/issues/issue-12133-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12133-2.rs b/src/test/run-pass/issues/issue-12133-2.rs deleted file mode 100644 index 02fec65c2ed..00000000000 --- a/src/test/run-pass/issues/issue-12133-2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12133-3.rs b/src/test/run-pass/issues/issue-12133-3.rs deleted file mode 100644 index c8aa9bf4649..00000000000 --- a/src/test/run-pass/issues/issue-12133-3.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12285.rs b/src/test/run-pass/issues/issue-12285.rs deleted file mode 100644 index 24ac5d2fbbf..00000000000 --- a/src/test/run-pass/issues/issue-12285.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -struct S; - -fn main() { - match Some(&S) { - Some(&S) => {}, - _x => unreachable!() - } - match Some(&S) { - Some(&S) => {}, - None => unreachable!() - } -} diff --git a/src/test/run-pass/issues/issue-1257.rs b/src/test/run-pass/issues/issue-1257.rs deleted file mode 100644 index de5a6d35925..00000000000 --- a/src/test/run-pass/issues/issue-1257.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12582.rs b/src/test/run-pass/issues/issue-12582.rs deleted file mode 100644 index f3366704e63..00000000000 --- a/src/test/run-pass/issues/issue-12582.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12612.rs b/src/test/run-pass/issues/issue-12612.rs deleted file mode 100644 index d254f6941a3..00000000000 --- a/src/test/run-pass/issues/issue-12612.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12660.rs b/src/test/run-pass/issues/issue-12660.rs deleted file mode 100644 index 44c492b43f0..00000000000 --- a/src/test/run-pass/issues/issue-12660.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12677.rs b/src/test/run-pass/issues/issue-12677.rs deleted file mode 100644 index d0e4c17d4fa..00000000000 --- a/src/test/run-pass/issues/issue-12677.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -fn main() { - let s = "Hello"; - let first = s.bytes(); - let second = first.clone(); - - assert_eq!(first.collect::>(), second.collect::>()) -} diff --git a/src/test/run-pass/issues/issue-12699.rs b/src/test/run-pass/issues/issue-12699.rs deleted file mode 100644 index e26c2d7cde2..00000000000 --- a/src/test/run-pass/issues/issue-12699.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12744.rs b/src/test/run-pass/issues/issue-12744.rs deleted file mode 100644 index e2756ec970c..00000000000 --- a/src/test/run-pass/issues/issue-12744.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -fn main() { - fn test() -> Box { Box::new(1) } - println!("{:?}", test()) -} diff --git a/src/test/run-pass/issues/issue-12860.rs b/src/test/run-pass/issues/issue-12860.rs deleted file mode 100644 index 01b642cdfcc..00000000000 --- a/src/test/run-pass/issues/issue-12860.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/issues/issue-12909.rs b/src/test/run-pass/issues/issue-12909.rs deleted file mode 100644 index a68d73a004f..00000000000 --- a/src/test/run-pass/issues/issue-12909.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13027.rs b/src/test/run-pass/issues/issue-13027.rs deleted file mode 100644 index 1bab82a543f..00000000000 --- a/src/test/run-pass/issues/issue-13027.rs +++ /dev/null @@ -1,178 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13204.rs b/src/test/run-pass/issues/issue-13204.rs deleted file mode 100644 index 3d6aba8455a..00000000000 --- a/src/test/run-pass/issues/issue-13204.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs b/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs deleted file mode 100644 index 740e7780de6..00000000000 --- a/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13264.rs b/src/test/run-pass/issues/issue-13264.rs deleted file mode 100644 index 691bb63a2fe..00000000000 --- a/src/test/run-pass/issues/issue-13264.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13304.rs b/src/test/run-pass/issues/issue-13304.rs deleted file mode 100644 index 5698536ab5d..00000000000 --- a/src/test/run-pass/issues/issue-13304.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13323.rs b/src/test/run-pass/issues/issue-13323.rs deleted file mode 100644 index 26847ee7a08..00000000000 --- a/src/test/run-pass/issues/issue-13323.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13434.rs b/src/test/run-pass/issues/issue-13434.rs deleted file mode 100644 index 1b7d3e20173..00000000000 --- a/src/test/run-pass/issues/issue-13434.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13507-2.rs b/src/test/run-pass/issues/issue-13507-2.rs deleted file mode 100644 index 63f3589c6cc..00000000000 --- a/src/test/run-pass/issues/issue-13507-2.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13620.rs b/src/test/run-pass/issues/issue-13620.rs deleted file mode 100644 index 3c3c19df75d..00000000000 --- a/src/test/run-pass/issues/issue-13620.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13655.rs b/src/test/run-pass/issues/issue-13655.rs deleted file mode 100644 index 6dd1847995f..00000000000 --- a/src/test/run-pass/issues/issue-13655.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13665.rs b/src/test/run-pass/issues/issue-13665.rs deleted file mode 100644 index a3843c65034..00000000000 --- a/src/test/run-pass/issues/issue-13665.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13763.rs b/src/test/run-pass/issues/issue-13763.rs deleted file mode 100644 index dd5f6dbc9dc..00000000000 --- a/src/test/run-pass/issues/issue-13763.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13808.rs b/src/test/run-pass/issues/issue-13808.rs deleted file mode 100644 index 9f9db067bf4..00000000000 --- a/src/test/run-pass/issues/issue-13808.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13867.rs b/src/test/run-pass/issues/issue-13867.rs deleted file mode 100644 index e66368f9ba8..00000000000 --- a/src/test/run-pass/issues/issue-13867.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13872.rs b/src/test/run-pass/issues/issue-13872.rs deleted file mode 100644 index aade6b8367c..00000000000 --- a/src/test/run-pass/issues/issue-13872.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-13902.rs b/src/test/run-pass/issues/issue-13902.rs deleted file mode 100644 index 1afde0ebe85..00000000000 --- a/src/test/run-pass/issues/issue-13902.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14229.rs b/src/test/run-pass/issues/issue-14229.rs deleted file mode 100644 index 477a2c65053..00000000000 --- a/src/test/run-pass/issues/issue-14229.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14308.rs b/src/test/run-pass/issues/issue-14308.rs deleted file mode 100644 index e067bcdf34a..00000000000 --- a/src/test/run-pass/issues/issue-14308.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14344.rs b/src/test/run-pass/issues/issue-14344.rs deleted file mode 100644 index 33b1df827d3..00000000000 --- a/src/test/run-pass/issues/issue-14344.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14382.rs b/src/test/run-pass/issues/issue-14382.rs deleted file mode 100644 index 671e7a22667..00000000000 --- a/src/test/run-pass/issues/issue-14382.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14393.rs b/src/test/run-pass/issues/issue-14393.rs deleted file mode 100644 index df635407af6..00000000000 --- a/src/test/run-pass/issues/issue-14393.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - match ("", 1_usize) { - (_, 42_usize) => (), - ("", _) => (), - _ => () - } -} diff --git a/src/test/run-pass/issues/issue-14399.rs b/src/test/run-pass/issues/issue-14399.rs deleted file mode 100644 index 6bf8a589959..00000000000 --- a/src/test/run-pass/issues/issue-14399.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14421.rs b/src/test/run-pass/issues/issue-14421.rs deleted file mode 100644 index c59bd87065f..00000000000 --- a/src/test/run-pass/issues/issue-14421.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14422.rs b/src/test/run-pass/issues/issue-14422.rs deleted file mode 100644 index b9e2065d014..00000000000 --- a/src/test/run-pass/issues/issue-14422.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14456.rs b/src/test/run-pass/issues/issue-14456.rs deleted file mode 100644 index 164d7ef8af2..00000000000 --- a/src/test/run-pass/issues/issue-14456.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1451.rs b/src/test/run-pass/issues/issue-1451.rs deleted file mode 100644 index ad8928b2043..00000000000 --- a/src/test/run-pass/issues/issue-1451.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14589.rs b/src/test/run-pass/issues/issue-14589.rs deleted file mode 100644 index 5d8aab2ce74..00000000000 --- a/src/test/run-pass/issues/issue-14589.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1460.rs b/src/test/run-pass/issues/issue-1460.rs deleted file mode 100644 index 143a0387e21..00000000000 --- a/src/test/run-pass/issues/issue-1460.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -// pretty-expanded FIXME #23616 - -pub fn main() { - {|i: u32| if 1 == i { }}; -} diff --git a/src/test/run-pass/issues/issue-14821.rs b/src/test/run-pass/issues/issue-14821.rs deleted file mode 100644 index 00b2e3607fc..00000000000 --- a/src/test/run-pass/issues/issue-14821.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14865.rs b/src/test/run-pass/issues/issue-14865.rs deleted file mode 100644 index 56e78e78f18..00000000000 --- a/src/test/run-pass/issues/issue-14865.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14875.rs b/src/test/run-pass/issues/issue-14875.rs deleted file mode 100644 index a2fd7962458..00000000000 --- a/src/test/run-pass/issues/issue-14875.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// ignore-wasm32-bare always compiled as panic=abort right now - -// 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/src/test/run-pass/issues/issue-14919.rs b/src/test/run-pass/issues/issue-14919.rs deleted file mode 100644 index 94361543354..00000000000 --- a/src/test/run-pass/issues/issue-14919.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14940.rs b/src/test/run-pass/issues/issue-14940.rs deleted file mode 100644 index 785ad6a2c49..00000000000 --- a/src/test/run-pass/issues/issue-14940.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-14958.rs b/src/test/run-pass/issues/issue-14958.rs deleted file mode 100644 index a12564ca9c0..00000000000 --- a/src/test/run-pass/issues/issue-14958.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15043.rs b/src/test/run-pass/issues/issue-15043.rs deleted file mode 100644 index 53748be8a02..00000000000 --- a/src/test/run-pass/issues/issue-15043.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15063.rs b/src/test/run-pass/issues/issue-15063.rs deleted file mode 100644 index 4082675129d..00000000000 --- a/src/test/run-pass/issues/issue-15063.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15080.rs b/src/test/run-pass/issues/issue-15080.rs deleted file mode 100644 index 4558118a809..00000000000 --- a/src/test/run-pass/issues/issue-15080.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/issues/issue-15104.rs b/src/test/run-pass/issues/issue-15104.rs deleted file mode 100644 index 3a03a52c324..00000000000 --- a/src/test/run-pass/issues/issue-15104.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/issues/issue-15155.rs b/src/test/run-pass/issues/issue-15155.rs deleted file mode 100644 index 7b137b4af56..00000000000 --- a/src/test/run-pass/issues/issue-15155.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15189.rs b/src/test/run-pass/issues/issue-15189.rs deleted file mode 100644 index a9c884bdcfd..00000000000 --- a/src/test/run-pass/issues/issue-15189.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15221.rs b/src/test/run-pass/issues/issue-15221.rs deleted file mode 100644 index 4b8319a8304..00000000000 --- a/src/test/run-pass/issues/issue-15221.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15444.rs b/src/test/run-pass/issues/issue-15444.rs deleted file mode 100644 index e94afee9634..00000000000 --- a/src/test/run-pass/issues/issue-15444.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15487.rs b/src/test/run-pass/issues/issue-15487.rs deleted file mode 100644 index 98714cba0e4..00000000000 --- a/src/test/run-pass/issues/issue-15487.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![allow(unused_attributes)] -// ignore-windows -// ignore-wasm32-bare no libs to link - -#![feature(link_args)] - -#[link_args="-lc -lm"] -#[link_args=" -lc"] -#[link_args="-lc "] -extern {} - -fn main() {} diff --git a/src/test/run-pass/issues/issue-15523-big.rs b/src/test/run-pass/issues/issue-15523-big.rs deleted file mode 100644 index 05414f1db72..00000000000 --- a/src/test/run-pass/issues/issue-15523-big.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15523.rs b/src/test/run-pass/issues/issue-15523.rs deleted file mode 100644 index 220a34b9b0f..00000000000 --- a/src/test/run-pass/issues/issue-15523.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15562.rs b/src/test/run-pass/issues/issue-15562.rs deleted file mode 100644 index b37ba81e291..00000000000 --- a/src/test/run-pass/issues/issue-15562.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15571.rs b/src/test/run-pass/issues/issue-15571.rs deleted file mode 100644 index 5381d65232f..00000000000 --- a/src/test/run-pass/issues/issue-15571.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15673.rs b/src/test/run-pass/issues/issue-15673.rs deleted file mode 100644 index a8733d7f157..00000000000 --- a/src/test/run-pass/issues/issue-15673.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15689-1.rs b/src/test/run-pass/issues/issue-15689-1.rs deleted file mode 100644 index d143926b281..00000000000 --- a/src/test/run-pass/issues/issue-15689-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -#[derive(PartialEq, Debug)] -enum Test<'a> { - Slice(&'a isize) -} - -fn main() { - assert_eq!(Test::Slice(&1), Test::Slice(&1)) -} diff --git a/src/test/run-pass/issues/issue-15730.rs b/src/test/run-pass/issues/issue-15730.rs deleted file mode 100644 index dacffd154fc..00000000000 --- a/src/test/run-pass/issues/issue-15730.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15734.rs b/src/test/run-pass/issues/issue-15734.rs deleted file mode 100644 index be582060601..00000000000 --- a/src/test/run-pass/issues/issue-15734.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15763.rs b/src/test/run-pass/issues/issue-15763.rs deleted file mode 100644 index 9ceffff2e38..00000000000 --- a/src/test/run-pass/issues/issue-15763.rs +++ /dev/null @@ -1,89 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15774.rs b/src/test/run-pass/issues/issue-15774.rs deleted file mode 100644 index ed2235758b9..00000000000 --- a/src/test/run-pass/issues/issue-15774.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15793.rs b/src/test/run-pass/issues/issue-15793.rs deleted file mode 100644 index 769012b1ba7..00000000000 --- a/src/test/run-pass/issues/issue-15793.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15858.rs b/src/test/run-pass/issues/issue-15858.rs deleted file mode 100644 index 41d2f13952a..00000000000 --- a/src/test/run-pass/issues/issue-15858.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs b/src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs deleted file mode 100644 index dee7f25d7bb..00000000000 --- a/src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16151.rs b/src/test/run-pass/issues/issue-16151.rs deleted file mode 100644 index 48a14b2af7c..00000000000 --- a/src/test/run-pass/issues/issue-16151.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16256.rs b/src/test/run-pass/issues/issue-16256.rs deleted file mode 100644 index e566eede8d2..00000000000 --- a/src/test/run-pass/issues/issue-16256.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - let mut buf = Vec::new(); - |c: u8| buf.push(c); -} diff --git a/src/test/run-pass/issues/issue-16272.rs b/src/test/run-pass/issues/issue-16272.rs deleted file mode 100644 index 3ba2483f430..00000000000 --- a/src/test/run-pass/issues/issue-16272.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16278.rs b/src/test/run-pass/issues/issue-16278.rs deleted file mode 100644 index 2f47b694ae9..00000000000 --- a/src/test/run-pass/issues/issue-16278.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16441.rs b/src/test/run-pass/issues/issue-16441.rs deleted file mode 100644 index bae3813f9da..00000000000 --- a/src/test/run-pass/issues/issue-16441.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -struct Empty; - -// This used to cause an ICE -extern "C" fn ice(_a: Empty) {} - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-16452.rs b/src/test/run-pass/issues/issue-16452.rs deleted file mode 100644 index faf9edd3b26..00000000000 --- a/src/test/run-pass/issues/issue-16452.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -fn main() { - if true { return } - match () { - () => { static MAGIC: usize = 0; } - } -} diff --git a/src/test/run-pass/issues/issue-16492.rs b/src/test/run-pass/issues/issue-16492.rs deleted file mode 100644 index 7fa808237bf..00000000000 --- a/src/test/run-pass/issues/issue-16492.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16530.rs b/src/test/run-pass/issues/issue-16530.rs deleted file mode 100644 index 22a6ef7fa09..00000000000 --- a/src/test/run-pass/issues/issue-16530.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -#![allow(deprecated)] - -use std::hash::{SipHasher, Hasher, Hash}; - -#[derive(Hash)] -struct Empty; - -pub fn main() { - let mut s1 = SipHasher::new_with_keys(0, 0); - Empty.hash(&mut s1); - let mut s2 = SipHasher::new_with_keys(0, 0); - Empty.hash(&mut s2); - assert_eq!(s1.finish(), s2.finish()); -} diff --git a/src/test/run-pass/issues/issue-16560.rs b/src/test/run-pass/issues/issue-16560.rs deleted file mode 100644 index d5fffc7ef9b..00000000000 --- a/src/test/run-pass/issues/issue-16560.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16597-empty.rs b/src/test/run-pass/issues/issue-16597-empty.rs deleted file mode 100644 index 2bdd08575c4..00000000000 --- a/src/test/run-pass/issues/issue-16597-empty.rs +++ /dev/null @@ -1,5 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16597.rs b/src/test/run-pass/issues/issue-16597.rs deleted file mode 100644 index 35769bfc117..00000000000 --- a/src/test/run-pass/issues/issue-16597.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(unused_imports)] -// compile-flags:--test - -mod tests { - use super::*; - - #[test] - pub fn test(){} -} diff --git a/src/test/run-pass/issues/issue-1660.rs b/src/test/run-pass/issues/issue-1660.rs deleted file mode 100644 index aa60a8d8a96..00000000000 --- a/src/test/run-pass/issues/issue-1660.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(non_upper_case_globals)] - -// pretty-expanded FIXME #23616 - -pub fn main() { - static _x: isize = 1<<2; -} diff --git a/src/test/run-pass/issues/issue-16602-1.rs b/src/test/run-pass/issues/issue-16602-1.rs deleted file mode 100644 index dd64ee75b34..00000000000 --- a/src/test/run-pass/issues/issue-16602-1.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -fn main() { - let mut t = [1; 2]; - t = [t[1] * 2, t[0] * 2]; - assert_eq!(&t[..], &[2, 2]); -} diff --git a/src/test/run-pass/issues/issue-16602-2.rs b/src/test/run-pass/issues/issue-16602-2.rs deleted file mode 100644 index 6364630ffa9..00000000000 --- a/src/test/run-pass/issues/issue-16602-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16602-3.rs b/src/test/run-pass/issues/issue-16602-3.rs deleted file mode 100644 index dbfeef053da..00000000000 --- a/src/test/run-pass/issues/issue-16602-3.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16643.rs b/src/test/run-pass/issues/issue-16643.rs deleted file mode 100644 index c74a554af2e..00000000000 --- a/src/test/run-pass/issues/issue-16643.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16648.rs b/src/test/run-pass/issues/issue-16648.rs deleted file mode 100644 index 539f015fa28..00000000000 --- a/src/test/run-pass/issues/issue-16648.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16671.rs b/src/test/run-pass/issues/issue-16671.rs deleted file mode 100644 index eff8e275bb5..00000000000 --- a/src/test/run-pass/issues/issue-16671.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - -#![deny(warnings)] - -fn foo(_f: F) { } - -fn main() { - let mut var = Vec::new(); - foo(move|| { - var.push(1); - }); -} diff --git a/src/test/run-pass/issues/issue-16739.rs b/src/test/run-pass/issues/issue-16739.rs deleted file mode 100644 index 54ad8fd076e..00000000000 --- a/src/test/run-pass/issues/issue-16739.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16745.rs b/src/test/run-pass/issues/issue-16745.rs deleted file mode 100644 index e9137df0f1e..00000000000 --- a/src/test/run-pass/issues/issue-16745.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16774.rs b/src/test/run-pass/issues/issue-16774.rs deleted file mode 100644 index 9e9b84034db..00000000000 --- a/src/test/run-pass/issues/issue-16774.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-16783.rs b/src/test/run-pass/issues/issue-16783.rs deleted file mode 100644 index 4af4031d278..00000000000 --- a/src/test/run-pass/issues/issue-16783.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -pub fn main() { - let x = [1, 2, 3]; - let y = x; -} diff --git a/src/test/run-pass/issues/issue-16819.rs b/src/test/run-pass/issues/issue-16819.rs deleted file mode 100644 index cc0200904e5..00000000000 --- a/src/test/run-pass/issues/issue-16819.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1696.rs b/src/test/run-pass/issues/issue-1696.rs deleted file mode 100644 index b5d77df3a18..00000000000 --- a/src/test/run-pass/issues/issue-1696.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1701.rs b/src/test/run-pass/issues/issue-1701.rs deleted file mode 100644 index bae32a77765..00000000000 --- a/src/test/run-pass/issues/issue-1701.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17068.rs b/src/test/run-pass/issues/issue-17068.rs deleted file mode 100644 index fe2c1a34bb4..00000000000 --- a/src/test/run-pass/issues/issue-17068.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17074.rs b/src/test/run-pass/issues/issue-17074.rs deleted file mode 100644 index 0ed81132ec6..00000000000 --- a/src/test/run-pass/issues/issue-17074.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17170.rs b/src/test/run-pass/issues/issue-17170.rs deleted file mode 100644 index 8d70dacdc90..00000000000 --- a/src/test/run-pass/issues/issue-17170.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17216.rs b/src/test/run-pass/issues/issue-17216.rs deleted file mode 100644 index 05baa1bffdd..00000000000 --- a/src/test/run-pass/issues/issue-17216.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17233.rs b/src/test/run-pass/issues/issue-17233.rs deleted file mode 100644 index 54a12fdf8e8..00000000000 --- a/src/test/run-pass/issues/issue-17233.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17302.rs b/src/test/run-pass/issues/issue-17302.rs deleted file mode 100644 index cf7a2f1b063..00000000000 --- a/src/test/run-pass/issues/issue-17302.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17322.rs b/src/test/run-pass/issues/issue-17322.rs deleted file mode 100644 index 20a8d136124..00000000000 --- a/src/test/run-pass/issues/issue-17322.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17351.rs b/src/test/run-pass/issues/issue-17351.rs deleted file mode 100644 index 62f6bcf15e3..00000000000 --- a/src/test/run-pass/issues/issue-17351.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17361.rs b/src/test/run-pass/issues/issue-17361.rs deleted file mode 100644 index e97fc3afd1c..00000000000 --- a/src/test/run-pass/issues/issue-17361.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17503.rs b/src/test/run-pass/issues/issue-17503.rs deleted file mode 100644 index 9a92c06e159..00000000000 --- a/src/test/run-pass/issues/issue-17503.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17662.rs b/src/test/run-pass/issues/issue-17662.rs deleted file mode 100644 index a2683808b52..00000000000 --- a/src/test/run-pass/issues/issue-17662.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17718-borrow-interior.rs b/src/test/run-pass/issues/issue-17718-borrow-interior.rs deleted file mode 100644 index 5861f218689..00000000000 --- a/src/test/run-pass/issues/issue-17718-borrow-interior.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17718-parse-const.rs b/src/test/run-pass/issues/issue-17718-parse-const.rs deleted file mode 100644 index d5a5f445d5b..00000000000 --- a/src/test/run-pass/issues/issue-17718-parse-const.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -const FOO: usize = 3; - -fn main() { - assert_eq!(FOO, 3); -} diff --git a/src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs deleted file mode 100644 index 65a8713ba05..00000000000 --- a/src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17718.rs b/src/test/run-pass/issues/issue-17718.rs deleted file mode 100644 index c6341d80844..00000000000 --- a/src/test/run-pass/issues/issue-17718.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17734.rs b/src/test/run-pass/issues/issue-17734.rs deleted file mode 100644 index ba8d6c21ca8..00000000000 --- a/src/test/run-pass/issues/issue-17734.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17756.rs b/src/test/run-pass/issues/issue-17756.rs deleted file mode 100644 index 1835b177ff3..00000000000 --- a/src/test/run-pass/issues/issue-17756.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17771.rs b/src/test/run-pass/issues/issue-17771.rs deleted file mode 100644 index 2f6464668c2..00000000000 --- a/src/test/run-pass/issues/issue-17771.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17816.rs b/src/test/run-pass/issues/issue-17816.rs deleted file mode 100644 index 7ca47d50335..00000000000 --- a/src/test/run-pass/issues/issue-17816.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-17877.rs b/src/test/run-pass/issues/issue-17877.rs deleted file mode 100644 index af22b1ad8f0..00000000000 --- a/src/test/run-pass/issues/issue-17877.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/issues/issue-17897.rs b/src/test/run-pass/issues/issue-17897.rs deleted file mode 100644 index 6873c7ccb7f..00000000000 --- a/src/test/run-pass/issues/issue-17897.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18060.rs b/src/test/run-pass/issues/issue-18060.rs deleted file mode 100644 index b5f3d0f74bc..00000000000 --- a/src/test/run-pass/issues/issue-18060.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18075.rs b/src/test/run-pass/issues/issue-18075.rs deleted file mode 100644 index ee6845c1278..00000000000 --- a/src/test/run-pass/issues/issue-18075.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// exec-env:RUSTC_LOG=rustc::middle=debug - -fn main() { - let b = 1isize; - println!("{}", b); -} diff --git a/src/test/run-pass/issues/issue-18110.rs b/src/test/run-pass/issues/issue-18110.rs deleted file mode 100644 index 41c29e77da5..00000000000 --- a/src/test/run-pass/issues/issue-18110.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![allow(unreachable_code)] -// pretty-expanded FIXME #23616 - -fn main() { - ({return},); -} diff --git a/src/test/run-pass/issues/issue-18173.rs b/src/test/run-pass/issues/issue-18173.rs deleted file mode 100644 index 11468040ee5..00000000000 --- a/src/test/run-pass/issues/issue-18173.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18232.rs b/src/test/run-pass/issues/issue-18232.rs deleted file mode 100644 index 7e6f6ef0f39..00000000000 --- a/src/test/run-pass/issues/issue-18232.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18352.rs b/src/test/run-pass/issues/issue-18352.rs deleted file mode 100644 index 5d93ed0646c..00000000000 --- a/src/test/run-pass/issues/issue-18352.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18353.rs b/src/test/run-pass/issues/issue-18353.rs deleted file mode 100644 index 3d15c9980c3..00000000000 --- a/src/test/run-pass/issues/issue-18353.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18412.rs b/src/test/run-pass/issues/issue-18412.rs deleted file mode 100644 index fe1cfb3dffa..00000000000 --- a/src/test/run-pass/issues/issue-18412.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18425.rs b/src/test/run-pass/issues/issue-18425.rs deleted file mode 100644 index 354c14a756a..00000000000 --- a/src/test/run-pass/issues/issue-18425.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18464.rs b/src/test/run-pass/issues/issue-18464.rs deleted file mode 100644 index 14d2d0a6c8d..00000000000 --- a/src/test/run-pass/issues/issue-18464.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18501.rs b/src/test/run-pass/issues/issue-18501.rs deleted file mode 100644 index 0ca23074c55..00000000000 --- a/src/test/run-pass/issues/issue-18501.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18514.rs b/src/test/run-pass/issues/issue-18514.rs deleted file mode 100644 index 48e7f07418f..00000000000 --- a/src/test/run-pass/issues/issue-18514.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18539.rs b/src/test/run-pass/issues/issue-18539.rs deleted file mode 100644 index 745df26e320..00000000000 --- a/src/test/run-pass/issues/issue-18539.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18652.rs b/src/test/run-pass/issues/issue-18652.rs deleted file mode 100644 index 59aa0156842..00000000000 --- a/src/test/run-pass/issues/issue-18652.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18655.rs b/src/test/run-pass/issues/issue-18655.rs deleted file mode 100644 index 3d18542acdc..00000000000 --- a/src/test/run-pass/issues/issue-18655.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -trait Factory { - type Product; - fn create(&self) -> ::Product; -} - -impl Factory for f64 { - type Product = f64; - fn create(&self) -> f64 { *self * *self } -} - -impl Factory for (A, B) { - type Product = (::Product, ::Product); - fn create(&self) -> (::Product, ::Product) { - let (ref a, ref b) = *self; - (a.create(), b.create()) - } -} - -fn main() { - assert_eq!((16., 25.), (4., 5.).create()); -} diff --git a/src/test/run-pass/issues/issue-18661.rs b/src/test/run-pass/issues/issue-18661.rs deleted file mode 100644 index e2427243235..00000000000 --- a/src/test/run-pass/issues/issue-18661.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18685.rs b/src/test/run-pass/issues/issue-18685.rs deleted file mode 100644 index bfe24b663f6..00000000000 --- a/src/test/run-pass/issues/issue-18685.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18711.rs b/src/test/run-pass/issues/issue-18711.rs deleted file mode 100644 index 43584187752..00000000000 --- a/src/test/run-pass/issues/issue-18711.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18767.rs b/src/test/run-pass/issues/issue-18767.rs deleted file mode 100644 index 2a5721b7295..00000000000 --- a/src/test/run-pass/issues/issue-18767.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18804/auxiliary/lib.rs b/src/test/run-pass/issues/issue-18804/auxiliary/lib.rs deleted file mode 100644 index ae27dd520e9..00000000000 --- a/src/test/run-pass/issues/issue-18804/auxiliary/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![crate_type = "rlib"] -#![feature(linkage)] - -pub fn foo() -> *const() { - extern { - #[linkage = "extern_weak"] - static FOO: *const(); - } - unsafe { FOO } -} diff --git a/src/test/run-pass/issues/issue-18804/main.rs b/src/test/run-pass/issues/issue-18804/main.rs deleted file mode 100644 index c36048ea545..00000000000 --- a/src/test/run-pass/issues/issue-18804/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18845.rs b/src/test/run-pass/issues/issue-18845.rs deleted file mode 100644 index 83fab4b5e8f..00000000000 --- a/src/test/run-pass/issues/issue-18845.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18859.rs b/src/test/run-pass/issues/issue-18859.rs deleted file mode 100644 index c4575bce925..00000000000 --- a/src/test/run-pass/issues/issue-18859.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18913.rs b/src/test/run-pass/issues/issue-18913.rs deleted file mode 100644 index 27fae6d7757..00000000000 --- a/src/test/run-pass/issues/issue-18913.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18937-1.rs b/src/test/run-pass/issues/issue-18937-1.rs deleted file mode 100644 index 57e56d832c6..00000000000 --- a/src/test/run-pass/issues/issue-18937-1.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-18952.rs b/src/test/run-pass/issues/issue-18952.rs deleted file mode 100644 index 56378b59e36..00000000000 --- a/src/test/run-pass/issues/issue-18952.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19001.rs b/src/test/run-pass/issues/issue-19001.rs deleted file mode 100644 index 76c380c2fc9..00000000000 --- a/src/test/run-pass/issues/issue-19001.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19127.rs b/src/test/run-pass/issues/issue-19127.rs deleted file mode 100644 index c847ac9e435..00000000000 --- a/src/test/run-pass/issues/issue-19127.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19135.rs b/src/test/run-pass/issues/issue-19135.rs deleted file mode 100644 index 84540a3ff5f..00000000000 --- a/src/test/run-pass/issues/issue-19135.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19244.rs b/src/test/run-pass/issues/issue-19244.rs deleted file mode 100644 index 44d9748fd2a..00000000000 --- a/src/test/run-pass/issues/issue-19244.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19293.rs b/src/test/run-pass/issues/issue-19293.rs deleted file mode 100644 index b6e9e3d065a..00000000000 --- a/src/test/run-pass/issues/issue-19293.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19340-1.rs b/src/test/run-pass/issues/issue-19340-1.rs deleted file mode 100644 index e3cc2daae9b..00000000000 --- a/src/test/run-pass/issues/issue-19340-1.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19340-2.rs b/src/test/run-pass/issues/issue-19340-2.rs deleted file mode 100644 index a222e9e4621..00000000000 --- a/src/test/run-pass/issues/issue-19340-2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19358.rs b/src/test/run-pass/issues/issue-19358.rs deleted file mode 100644 index f66e0a1c078..00000000000 --- a/src/test/run-pass/issues/issue-19358.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19367.rs b/src/test/run-pass/issues/issue-19367.rs deleted file mode 100644 index 0699533e72b..00000000000 --- a/src/test/run-pass/issues/issue-19367.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19499.rs b/src/test/run-pass/issues/issue-19499.rs deleted file mode 100644 index d09056ce3de..00000000000 --- a/src/test/run-pass/issues/issue-19499.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-1974.rs b/src/test/run-pass/issues/issue-1974.rs deleted file mode 100644 index 74a54a6029e..00000000000 --- a/src/test/run-pass/issues/issue-1974.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-19811-escape-unicode.rs b/src/test/run-pass/issues/issue-19811-escape-unicode.rs deleted file mode 100644 index a2c50bc022d..00000000000 --- a/src/test/run-pass/issues/issue-19811-escape-unicode.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20055-box-trait.rs b/src/test/run-pass/issues/issue-20055-box-trait.rs deleted file mode 100644 index 772cd9d7eda..00000000000 --- a/src/test/run-pass/issues/issue-20055-box-trait.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20055-box-unsized-array.rs b/src/test/run-pass/issues/issue-20055-box-unsized-array.rs deleted file mode 100644 index 1246c80651f..00000000000 --- a/src/test/run-pass/issues/issue-20055-box-unsized-array.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20174.rs b/src/test/run-pass/issues/issue-20174.rs deleted file mode 100644 index 4ed5a97c172..00000000000 --- a/src/test/run-pass/issues/issue-20174.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -struct GradFn usize>(F); - -fn main() { - let GradFn(x_squared) : GradFn<_> = GradFn(|| -> usize { 2 }); - let _ = x_squared(); -} diff --git a/src/test/run-pass/issues/issue-20343.rs b/src/test/run-pass/issues/issue-20343.rs deleted file mode 100644 index 000b6398442..00000000000 --- a/src/test/run-pass/issues/issue-20343.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20389.rs b/src/test/run-pass/issues/issue-20389.rs deleted file mode 100644 index 9bc3efcc1c4..00000000000 --- a/src/test/run-pass/issues/issue-20389.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20427.rs b/src/test/run-pass/issues/issue-20427.rs deleted file mode 100644 index fa2ea6cf592..00000000000 --- a/src/test/run-pass/issues/issue-20427.rs +++ /dev/null @@ -1,88 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20544.rs b/src/test/run-pass/issues/issue-20544.rs deleted file mode 100644 index 0f4d314f166..00000000000 --- a/src/test/run-pass/issues/issue-20544.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20575.rs b/src/test/run-pass/issues/issue-20575.rs deleted file mode 100644 index 0ca67d9dc71..00000000000 --- a/src/test/run-pass/issues/issue-20575.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20616.rs b/src/test/run-pass/issues/issue-20616.rs deleted file mode 100644 index 6c24d437272..00000000000 --- a/src/test/run-pass/issues/issue-20616.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2063.rs b/src/test/run-pass/issues/issue-2063.rs deleted file mode 100644 index 9dbac6ccee1..00000000000 --- a/src/test/run-pass/issues/issue-2063.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20676.rs b/src/test/run-pass/issues/issue-20676.rs deleted file mode 100644 index 2bc5034960a..00000000000 --- a/src/test/run-pass/issues/issue-20676.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2074.rs b/src/test/run-pass/issues/issue-2074.rs deleted file mode 100644 index bd5f015cca0..00000000000 --- a/src/test/run-pass/issues/issue-2074.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20803.rs b/src/test/run-pass/issues/issue-20803.rs deleted file mode 100644 index f657cf6cdd7..00000000000 --- a/src/test/run-pass/issues/issue-20803.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -use std::ops::Add; - -fn foo(x: T) -> >::Output where i32: Add { - 42i32 + x -} - -fn main() { - println!("{}", foo(0i32)); -} diff --git a/src/test/run-pass/issues/issue-20823.rs b/src/test/run-pass/issues/issue-20823.rs deleted file mode 100644 index 9e209d5d33a..00000000000 --- a/src/test/run-pass/issues/issue-20823.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -// compile-flags: --test - -#[test] -pub fn foo() {} diff --git a/src/test/run-pass/issues/issue-20847.rs b/src/test/run-pass/issues/issue-20847.rs deleted file mode 100644 index 0cd7edf89db..00000000000 --- a/src/test/run-pass/issues/issue-20847.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-20953.rs b/src/test/run-pass/issues/issue-20953.rs deleted file mode 100644 index 4ec7e3195eb..00000000000 --- a/src/test/run-pass/issues/issue-20953.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21033.rs b/src/test/run-pass/issues/issue-21033.rs deleted file mode 100644 index 86cc7707e50..00000000000 --- a/src/test/run-pass/issues/issue-21033.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21058.rs b/src/test/run-pass/issues/issue-21058.rs deleted file mode 100644 index 6facf0b2dd5..00000000000 --- a/src/test/run-pass/issues/issue-21058.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21291.rs b/src/test/run-pass/issues/issue-21291.rs deleted file mode 100644 index b351e22d862..00000000000 --- a/src/test/run-pass/issues/issue-21291.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21306.rs b/src/test/run-pass/issues/issue-21306.rs deleted file mode 100644 index b06a475e4df..00000000000 --- a/src/test/run-pass/issues/issue-21306.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21361.rs b/src/test/run-pass/issues/issue-21361.rs deleted file mode 100644 index c970e77abb7..00000000000 --- a/src/test/run-pass/issues/issue-21361.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21384.rs b/src/test/run-pass/issues/issue-21384.rs deleted file mode 100644 index caa99a15982..00000000000 --- a/src/test/run-pass/issues/issue-21384.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21400.rs b/src/test/run-pass/issues/issue-21400.rs deleted file mode 100644 index 4a85158d97a..00000000000 --- a/src/test/run-pass/issues/issue-21400.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21475.rs b/src/test/run-pass/issues/issue-21475.rs deleted file mode 100644 index 16d003aba7c..00000000000 --- a/src/test/run-pass/issues/issue-21475.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -#![allow(unused_imports)] -// 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/src/test/run-pass/issues/issue-21486.rs b/src/test/run-pass/issues/issue-21486.rs deleted file mode 100644 index 46d6ccd56bd..00000000000 --- a/src/test/run-pass/issues/issue-21486.rs +++ /dev/null @@ -1,77 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21655.rs b/src/test/run-pass/issues/issue-21655.rs deleted file mode 100644 index d1cd4ec7b8a..00000000000 --- a/src/test/run-pass/issues/issue-21655.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2170-exe.rs b/src/test/run-pass/issues/issue-2170-exe.rs deleted file mode 100644 index a89579706c8..00000000000 --- a/src/test/run-pass/issues/issue-2170-exe.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21721.rs b/src/test/run-pass/issues/issue-21721.rs deleted file mode 100644 index 4c1411e1ecf..00000000000 --- a/src/test/run-pass/issues/issue-21721.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2190-1.rs b/src/test/run-pass/issues/issue-2190-1.rs deleted file mode 100644 index e67a924b9ee..00000000000 --- a/src/test/run-pass/issues/issue-2190-1.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21909.rs b/src/test/run-pass/issues/issue-21909.rs deleted file mode 100644 index 7cb558d9a4f..00000000000 --- a/src/test/run-pass/issues/issue-21909.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-21922.rs b/src/test/run-pass/issues/issue-21922.rs deleted file mode 100644 index 9727b2efe9a..00000000000 --- a/src/test/run-pass/issues/issue-21922.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22008.rs b/src/test/run-pass/issues/issue-22008.rs deleted file mode 100644 index 00425582266..00000000000 --- a/src/test/run-pass/issues/issue-22008.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -pub fn main() { - let command = "a"; - - match command { - "foo" => println!("foo"), - _ => println!("{}", command), - } -} diff --git a/src/test/run-pass/issues/issue-22036.rs b/src/test/run-pass/issues/issue-22036.rs deleted file mode 100644 index 30da2130a31..00000000000 --- a/src/test/run-pass/issues/issue-22036.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2214.rs b/src/test/run-pass/issues/issue-2214.rs deleted file mode 100644 index 22f33545cb9..00000000000 --- a/src/test/run-pass/issues/issue-2214.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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}; - - #[link_name = "m"] - extern { - #[cfg(any(unix, 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; - } -} - -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/src/test/run-pass/issues/issue-2216.rs b/src/test/run-pass/issues/issue-2216.rs deleted file mode 100644 index fa712edcd1b..00000000000 --- a/src/test/run-pass/issues/issue-2216.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -#![allow(unreachable_code)] -pub fn main() { - let mut x = 0; - - 'foo: loop { - 'bar: loop { - 'quux: loop { - if 1 == 2 { - break 'foo; - } - else { - break 'bar; - } - } - continue 'foo; - } - x = 42; - break; - } - - println!("{}", x); - assert_eq!(x, 42); -} diff --git a/src/test/run-pass/issues/issue-22258.rs b/src/test/run-pass/issues/issue-22258.rs deleted file mode 100644 index 93ead5818d5..00000000000 --- a/src/test/run-pass/issues/issue-22258.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22346.rs b/src/test/run-pass/issues/issue-22346.rs deleted file mode 100644 index 5f6d9dcc9ae..00000000000 --- a/src/test/run-pass/issues/issue-22346.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22403.rs b/src/test/run-pass/issues/issue-22403.rs deleted file mode 100644 index 8d855909435..00000000000 --- a/src/test/run-pass/issues/issue-22403.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -fn main() { - let x = Box::new([1, 2, 3]); - let y = x as Box<[i32]>; - println!("y: {:?}", y); -} diff --git a/src/test/run-pass/issues/issue-22426.rs b/src/test/run-pass/issues/issue-22426.rs deleted file mode 100644 index adf060a8292..00000000000 --- a/src/test/run-pass/issues/issue-22426.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - match 42 { - x if x < 7 => (), - _ => () - } -} diff --git a/src/test/run-pass/issues/issue-22463.rs b/src/test/run-pass/issues/issue-22463.rs deleted file mode 100644 index fdf5a2fca72..00000000000 --- a/src/test/run-pass/issues/issue-22463.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -macro_rules! items { - () => { - type A = (); - fn a() {} - } -} - -trait Foo { - type A; - fn a(); -} - -impl Foo for () { - items!(); -} - -fn main() { - -} diff --git a/src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs b/src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs deleted file mode 100644 index 017f36484c1..00000000000 --- a/src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22546.rs b/src/test/run-pass/issues/issue-22546.rs deleted file mode 100644 index c26e457f9e4..00000000000 --- a/src/test/run-pass/issues/issue-22546.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22577.rs b/src/test/run-pass/issues/issue-22577.rs deleted file mode 100644 index 24f4f60aa2f..00000000000 --- a/src/test/run-pass/issues/issue-22577.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22629.rs b/src/test/run-pass/issues/issue-22629.rs deleted file mode 100644 index 7beeb126ee4..00000000000 --- a/src/test/run-pass/issues/issue-22629.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22828.rs b/src/test/run-pass/issues/issue-22828.rs deleted file mode 100644 index adf4dd6ce75..00000000000 --- a/src/test/run-pass/issues/issue-22828.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Test transitive analysis for associated types. Collected types -// should be normalized and new obligations generated. - -// pretty-expanded FIXME #23616 - -trait Foo { - type A; - fn foo(&self) {} -} - -impl Foo for usize { - type A = usize; -} - -struct Bar { inner: T::A } - -fn is_send() {} - -fn main() { - is_send::>(); -} diff --git a/src/test/run-pass/issues/issue-2284.rs b/src/test/run-pass/issues/issue-2284.rs deleted file mode 100644 index 6f2c958341b..00000000000 --- a/src/test/run-pass/issues/issue-2284.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22864-1.rs b/src/test/run-pass/issues/issue-22864-1.rs deleted file mode 100644 index 0fad5433d6c..00000000000 --- a/src/test/run-pass/issues/issue-22864-1.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -pub fn main() { - struct Fun(F); - let f = Fun(|x| 3*x); - let Fun(g) = f; - println!("{:?}",g(4)); -} diff --git a/src/test/run-pass/issues/issue-22864-2.rs b/src/test/run-pass/issues/issue-22864-2.rs deleted file mode 100644 index 4aa9e3e086b..00000000000 --- a/src/test/run-pass/issues/issue-22864-2.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// ignore-emscripten no threads support - -pub fn main() { - let f = || || 0; - std::thread::spawn(f()); -} diff --git a/src/test/run-pass/issues/issue-2288.rs b/src/test/run-pass/issues/issue-2288.rs deleted file mode 100644 index c74e53fca60..00000000000 --- a/src/test/run-pass/issues/issue-2288.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22992-2.rs b/src/test/run-pass/issues/issue-22992-2.rs deleted file mode 100644 index 042af40eda6..00000000000 --- a/src/test/run-pass/issues/issue-22992-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-22992.rs b/src/test/run-pass/issues/issue-22992.rs deleted file mode 100644 index e2ae1f96ee5..00000000000 --- a/src/test/run-pass/issues/issue-22992.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23036.rs b/src/test/run-pass/issues/issue-23036.rs deleted file mode 100644 index a307e7eed95..00000000000 --- a/src/test/run-pass/issues/issue-23036.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2316-c.rs b/src/test/run-pass/issues/issue-2316-c.rs deleted file mode 100644 index d975aa695c8..00000000000 --- a/src/test/run-pass/issues/issue-2316-c.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23208.rs b/src/test/run-pass/issues/issue-23208.rs deleted file mode 100644 index fd4ffe5d6e1..00000000000 --- a/src/test/run-pass/issues/issue-23208.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -trait TheTrait : TheSuperTrait<::Item> { - type Item; -} - -trait TheSuperTrait { - fn get(&self) -> T; -} - -impl TheTrait for i32 { - type Item = u32; -} - -impl TheSuperTrait for i32 { - fn get(&self) -> u32 { - *self as u32 - } -} - -fn foo>(t: &T) -> u32 { - t.get() -} - -fn main() { - foo::(&22); -} diff --git a/src/test/run-pass/issues/issue-23261.rs b/src/test/run-pass/issues/issue-23261.rs deleted file mode 100644 index e21f86351ee..00000000000 --- a/src/test/run-pass/issues/issue-23261.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23304-1.rs b/src/test/run-pass/issues/issue-23304-1.rs deleted file mode 100644 index 1805c1c19b9..00000000000 --- a/src/test/run-pass/issues/issue-23304-1.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23304-2.rs b/src/test/run-pass/issues/issue-23304-2.rs deleted file mode 100644 index 6376fdb6545..00000000000 --- a/src/test/run-pass/issues/issue-23304-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23311.rs b/src/test/run-pass/issues/issue-23311.rs deleted file mode 100644 index f275c6338b1..00000000000 --- a/src/test/run-pass/issues/issue-23311.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// Test that we do not ICE when pattern matching an array against a slice. - -#![feature(slice_patterns)] - -fn main() { - match "foo".as_bytes() { - b"food" => (), - &[b'f', ..] => (), - _ => () - } -} diff --git a/src/test/run-pass/issues/issue-23336.rs b/src/test/run-pass/issues/issue-23336.rs deleted file mode 100644 index cd71d7eed89..00000000000 --- a/src/test/run-pass/issues/issue-23336.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs b/src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs deleted file mode 100644 index 823be8c832d..00000000000 --- a/src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs +++ /dev/null @@ -1,164 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs b/src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs deleted file mode 100644 index d45aaa843fb..00000000000 --- a/src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23433.rs b/src/test/run-pass/issues/issue-23433.rs deleted file mode 100644 index d4fbbde62ff..00000000000 --- a/src/test/run-pass/issues/issue-23433.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23485.rs b/src/test/run-pass/issues/issue-23485.rs deleted file mode 100644 index 1dd3d9293bc..00000000000 --- a/src/test/run-pass/issues/issue-23485.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23491.rs b/src/test/run-pass/issues/issue-23491.rs deleted file mode 100644 index d2ded88aeff..00000000000 --- a/src/test/run-pass/issues/issue-23491.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(unused_variables)] -#![feature(box_syntax)] - -struct Node(T); - -fn main() { - let x: Box> = box Node([]); -} diff --git a/src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs b/src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs deleted file mode 100644 index 6ef7fd42ec6..00000000000 --- a/src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs +++ /dev/null @@ -1,258 +0,0 @@ -// 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) - } - }; - - 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/src/test/run-pass/issues/issue-23649-1.rs b/src/test/run-pass/issues/issue-23649-1.rs deleted file mode 100644 index fc0c9a605fa..00000000000 --- a/src/test/run-pass/issues/issue-23649-1.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23649-2.rs b/src/test/run-pass/issues/issue-23649-2.rs deleted file mode 100644 index f5fb8b65020..00000000000 --- a/src/test/run-pass/issues/issue-23649-2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23699.rs b/src/test/run-pass/issues/issue-23699.rs deleted file mode 100644 index 952548837e4..00000000000 --- a/src/test/run-pass/issues/issue-23699.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23781.rs b/src/test/run-pass/issues/issue-23781.rs deleted file mode 100644 index 220ebdb1872..00000000000 --- a/src/test/run-pass/issues/issue-23781.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2380-b.rs b/src/test/run-pass/issues/issue-2380-b.rs deleted file mode 100644 index d708c7b4213..00000000000 --- a/src/test/run-pass/issues/issue-2380-b.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:issue-2380.rs - -// pretty-expanded FIXME #23616 - -extern crate a; - -pub fn main() { - a::f::<()>(); -} diff --git a/src/test/run-pass/issues/issue-23808.rs b/src/test/run-pass/issues/issue-23808.rs deleted file mode 100644 index 0988b09fce9..00000000000 --- a/src/test/run-pass/issues/issue-23808.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23825.rs b/src/test/run-pass/issues/issue-23825.rs deleted file mode 100644 index a9f0095d2e2..00000000000 --- a/src/test/run-pass/issues/issue-23825.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2383.rs b/src/test/run-pass/issues/issue-2383.rs deleted file mode 100644 index 06e61ce680b..00000000000 --- a/src/test/run-pass/issues/issue-2383.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23833.rs b/src/test/run-pass/issues/issue-23833.rs deleted file mode 100644 index 77dc5c50d7a..00000000000 --- a/src/test/run-pass/issues/issue-23833.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23891.rs b/src/test/run-pass/issues/issue-23891.rs deleted file mode 100644 index 73467f715cb..00000000000 --- a/src/test/run-pass/issues/issue-23891.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23898.rs b/src/test/run-pass/issues/issue-23898.rs deleted file mode 100644 index a8787f279b7..00000000000 --- a/src/test/run-pass/issues/issue-23898.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![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/src/test/run-pass/issues/issue-23958.rs b/src/test/run-pass/issues/issue-23958.rs deleted file mode 100644 index 7e90d758600..00000000000 --- a/src/test/run-pass/issues/issue-23958.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23968-const-not-overflow.rs b/src/test/run-pass/issues/issue-23968-const-not-overflow.rs deleted file mode 100644 index b9593021235..00000000000 --- a/src/test/run-pass/issues/issue-23968-const-not-overflow.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-23992.rs b/src/test/run-pass/issues/issue-23992.rs deleted file mode 100644 index 1ff44bd7f2d..00000000000 --- a/src/test/run-pass/issues/issue-23992.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24010.rs b/src/test/run-pass/issues/issue-24010.rs deleted file mode 100644 index f1818533487..00000000000 --- a/src/test/run-pass/issues/issue-24010.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24086.rs b/src/test/run-pass/issues/issue-24086.rs deleted file mode 100644 index 54622afbcfc..00000000000 --- a/src/test/run-pass/issues/issue-24086.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2414-c.rs b/src/test/run-pass/issues/issue-2414-c.rs deleted file mode 100644 index f6fe9798067..00000000000 --- a/src/test/run-pass/issues/issue-2414-c.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2428.rs b/src/test/run-pass/issues/issue-2428.rs deleted file mode 100644 index 94b830de3e6..00000000000 --- a/src/test/run-pass/issues/issue-2428.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24308.rs b/src/test/run-pass/issues/issue-24308.rs deleted file mode 100644 index 9c39a5d2238..00000000000 --- a/src/test/run-pass/issues/issue-24308.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24313.rs b/src/test/run-pass/issues/issue-24313.rs deleted file mode 100644 index 2c420dc056f..00000000000 --- a/src/test/run-pass/issues/issue-24313.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24353.rs b/src/test/run-pass/issues/issue-24353.rs deleted file mode 100644 index f78255b7e2b..00000000000 --- a/src/test/run-pass/issues/issue-24353.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unreachable_code)] -fn main() { - return (); - - let x = (); - x -} diff --git a/src/test/run-pass/issues/issue-2445-b.rs b/src/test/run-pass/issues/issue-2445-b.rs deleted file mode 100644 index f369eae3af3..00000000000 --- a/src/test/run-pass/issues/issue-2445-b.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2445.rs b/src/test/run-pass/issues/issue-2445.rs deleted file mode 100644 index 5730ce16574..00000000000 --- a/src/test/run-pass/issues/issue-2445.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24533.rs b/src/test/run-pass/issues/issue-24533.rs deleted file mode 100644 index 8592bf43072..00000000000 --- a/src/test/run-pass/issues/issue-24533.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs deleted file mode 100644 index 48362d0bb62..00000000000 --- a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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 - -#![feature(bind_by_move_pattern_guards)] - -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/src/test/run-pass/issues/issue-24589.rs b/src/test/run-pass/issues/issue-24589.rs deleted file mode 100644 index 6b03e14f961..00000000000 --- a/src/test/run-pass/issues/issue-24589.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2463.rs b/src/test/run-pass/issues/issue-2463.rs deleted file mode 100644 index d24a47c53d9..00000000000 --- a/src/test/run-pass/issues/issue-2463.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs deleted file mode 100644 index 5b1b1389ceb..00000000000 --- a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![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/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs deleted file mode 100644 index 215145a64b1..00000000000 --- a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs deleted file mode 100644 index 773792c7a3f..00000000000 --- a/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// aux-build:issue-24687-lib.rs -// compile-flags:-g - -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/src/test/run-pass/issues/issue-2472.rs b/src/test/run-pass/issues/issue-2472.rs deleted file mode 100644 index c790bc2d095..00000000000 --- a/src/test/run-pass/issues/issue-2472.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24779.rs b/src/test/run-pass/issues/issue-24779.rs deleted file mode 100644 index f1283d0dcf5..00000000000 --- a/src/test/run-pass/issues/issue-24779.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - assert_eq!((||||42)()(), 42); -} diff --git a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs b/src/test/run-pass/issues/issue-24805-dropck-itemless.rs deleted file mode 100644 index 555eefeb3a1..00000000000 --- a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs +++ /dev/null @@ -1,77 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs b/src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs deleted file mode 100644 index cf3834952c6..00000000000 --- a/src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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 - -fn main() { - assert_eq!(1, 1); -} diff --git a/src/test/run-pass/issues/issue-24947.rs b/src/test/run-pass/issues/issue-24947.rs deleted file mode 100644 index 23705b4c9e7..00000000000 --- a/src/test/run-pass/issues/issue-24947.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-24954.rs b/src/test/run-pass/issues/issue-24954.rs deleted file mode 100644 index 0177dd4eae5..00000000000 --- a/src/test/run-pass/issues/issue-24954.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25089.rs b/src/test/run-pass/issues/issue-25089.rs deleted file mode 100644 index cf261d43c55..00000000000 --- a/src/test/run-pass/issues/issue-25089.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25145.rs b/src/test/run-pass/issues/issue-25145.rs deleted file mode 100644 index f5ae28fbbab..00000000000 --- a/src/test/run-pass/issues/issue-25145.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25185.rs b/src/test/run-pass/issues/issue-25185.rs deleted file mode 100644 index 383c9a1e9c4..00000000000 --- a/src/test/run-pass/issues/issue-25185.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2526-a.rs b/src/test/run-pass/issues/issue-2526-a.rs deleted file mode 100644 index f3fdc0bd377..00000000000 --- a/src/test/run-pass/issues/issue-2526-a.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25279.rs b/src/test/run-pass/issues/issue-25279.rs deleted file mode 100644 index fdc516d3761..00000000000 --- a/src/test/run-pass/issues/issue-25279.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25339.rs b/src/test/run-pass/issues/issue-25339.rs deleted file mode 100644 index 6f8ec700951..00000000000 --- a/src/test/run-pass/issues/issue-25339.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![feature(associated_type_defaults)] - -use std::marker::PhantomData; - -pub trait Routing { - type Output; - fn resolve(&self, input: I); -} - -pub trait ToRouting { - type Input; - type Routing : ?Sized = dyn Routing; - fn to_routing(self) -> Self::Routing; -} - -pub struct Mount> { - action: R, - _marker: PhantomData -} - -impl> Mount { - pub fn create>(mount: &str, input: T) { - input.to_routing(); - } -} - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-25343.rs b/src/test/run-pass/issues/issue-25343.rs deleted file mode 100644 index 95a0bd9155d..00000000000 --- a/src/test/run-pass/issues/issue-25343.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25467.rs b/src/test/run-pass/issues/issue-25467.rs deleted file mode 100644 index 31ac5f0f34b..00000000000 --- a/src/test/run-pass/issues/issue-25467.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25497.rs b/src/test/run-pass/issues/issue-25497.rs deleted file mode 100644 index 25f5ab90f7f..00000000000 --- a/src/test/run-pass/issues/issue-25497.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2550.rs b/src/test/run-pass/issues/issue-2550.rs deleted file mode 100644 index 04ec66b80d7..00000000000 --- a/src/test/run-pass/issues/issue-2550.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25515.rs b/src/test/run-pass/issues/issue-25515.rs deleted file mode 100644 index e7b9ea3acfc..00000000000 --- a/src/test/run-pass/issues/issue-25515.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25549-multiple-drop.rs b/src/test/run-pass/issues/issue-25549-multiple-drop.rs deleted file mode 100644 index 25a2da707dc..00000000000 --- a/src/test/run-pass/issues/issue-25549-multiple-drop.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25679.rs b/src/test/run-pass/issues/issue-25679.rs deleted file mode 100644 index 89544c9eb88..00000000000 --- a/src/test/run-pass/issues/issue-25679.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25693.rs b/src/test/run-pass/issues/issue-25693.rs deleted file mode 100644 index 9af0ba100e8..00000000000 --- a/src/test/run-pass/issues/issue-25693.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25700-1.rs b/src/test/run-pass/issues/issue-25700-1.rs deleted file mode 100644 index 7bc9673a5be..00000000000 --- a/src/test/run-pass/issues/issue-25700-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25700-2.rs b/src/test/run-pass/issues/issue-25700-2.rs deleted file mode 100644 index b161e68abaf..00000000000 --- a/src/test/run-pass/issues/issue-25700-2.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25746-bool-transmute.rs b/src/test/run-pass/issues/issue-25746-bool-transmute.rs deleted file mode 100644 index bc2f4a7c1b7..00000000000 --- a/src/test/run-pass/issues/issue-25746-bool-transmute.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25757.rs b/src/test/run-pass/issues/issue-25757.rs deleted file mode 100644 index ec1864d7deb..00000000000 --- a/src/test/run-pass/issues/issue-25757.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25810.rs b/src/test/run-pass/issues/issue-25810.rs deleted file mode 100644 index f32216f3254..00000000000 --- a/src/test/run-pass/issues/issue-25810.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-25916.rs b/src/test/run-pass/issues/issue-25916.rs deleted file mode 100644 index 0b415947965..00000000000 --- a/src/test/run-pass/issues/issue-25916.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26127.rs b/src/test/run-pass/issues/issue-26127.rs deleted file mode 100644 index cb479a23085..00000000000 --- a/src/test/run-pass/issues/issue-26127.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26251.rs b/src/test/run-pass/issues/issue-26251.rs deleted file mode 100644 index 0434ef9e5a9..00000000000 --- a/src/test/run-pass/issues/issue-26251.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -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/src/test/run-pass/issues/issue-2631-b.rs b/src/test/run-pass/issues/issue-2631-b.rs deleted file mode 100644 index c7f6728e3f2..00000000000 --- a/src/test/run-pass/issues/issue-2631-b.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26322.rs b/src/test/run-pass/issues/issue-26322.rs deleted file mode 100644 index c1dc80eb7c5..00000000000 --- a/src/test/run-pass/issues/issue-26322.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2633-2.rs b/src/test/run-pass/issues/issue-2633-2.rs deleted file mode 100644 index 02c1a166301..00000000000 --- a/src/test/run-pass/issues/issue-2633-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2633.rs b/src/test/run-pass/issues/issue-2633.rs deleted file mode 100644 index 7e8cea75fc8..00000000000 --- a/src/test/run-pass/issues/issue-2633.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2642.rs b/src/test/run-pass/issues/issue-2642.rs deleted file mode 100644 index 95c5632258e..00000000000 --- a/src/test/run-pass/issues/issue-2642.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -fn f() { - let _x: usize = loop { loop { break; } }; -} - -pub fn main() { -} diff --git a/src/test/run-pass/issues/issue-26468.rs b/src/test/run-pass/issues/issue-26468.rs deleted file mode 100644 index 71cc90e8bd1..00000000000 --- a/src/test/run-pass/issues/issue-26468.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26484.rs b/src/test/run-pass/issues/issue-26484.rs deleted file mode 100644 index 3b40b3dd8f0..00000000000 --- a/src/test/run-pass/issues/issue-26484.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// compile-flags:-g - -fn helper bool>(_f: F) { - print!(""); -} - -fn main() { - let cond = 0; - helper(|v| v == cond) -} diff --git a/src/test/run-pass/issues/issue-26641.rs b/src/test/run-pass/issues/issue-26641.rs deleted file mode 100644 index 4b6f2c2b3bc..00000000000 --- a/src/test/run-pass/issues/issue-26641.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -struct Parser<'a>(Box); - -fn main() { - let _x = Parser(Box::new(|_|{})); -} diff --git a/src/test/run-pass/issues/issue-26655.rs b/src/test/run-pass/issues/issue-26655.rs deleted file mode 100644 index 4c01183a440..00000000000 --- a/src/test/run-pass/issues/issue-26655.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26709.rs b/src/test/run-pass/issues/issue-26709.rs deleted file mode 100644 index 281ae13399d..00000000000 --- a/src/test/run-pass/issues/issue-26709.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26802.rs b/src/test/run-pass/issues/issue-26802.rs deleted file mode 100644 index 307a6716098..00000000000 --- a/src/test/run-pass/issues/issue-26802.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26805.rs b/src/test/run-pass/issues/issue-26805.rs deleted file mode 100644 index bcf8a673191..00000000000 --- a/src/test/run-pass/issues/issue-26805.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -struct NonOrd; - -fn main() { - let _: Box> = Box::new(vec![NonOrd].into_iter()); -} diff --git a/src/test/run-pass/issues/issue-26873-multifile.rs b/src/test/run-pass/issues/issue-26873-multifile.rs deleted file mode 100644 index da2acf6c9f7..00000000000 --- a/src/test/run-pass/issues/issue-26873-multifile.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26873-multifile/A/B.rs b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs deleted file mode 100644 index ab7b0d81605..00000000000 --- a/src/test/run-pass/issues/issue-26873-multifile/A/B.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -use super::*; - -pub struct S; diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/C.rs b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs deleted file mode 100644 index b287283df53..00000000000 --- a/src/test/run-pass/issues/issue-26873-multifile/A/C.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -use super::*; - -use super::B::S; - -pub struct T { i: i32 } diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs deleted file mode 100644 index 0f18772bf1b..00000000000 --- a/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -pub mod B; -pub mod C; - -pub use self::C::T; diff --git a/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir b/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/issues/issue-26873-multifile/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/mod.rs deleted file mode 100644 index a1ba53f9191..00000000000 --- a/src/test/run-pass/issues/issue-26873-multifile/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -mod A; - -use self::A::*; diff --git a/src/test/run-pass/issues/issue-26873-onefile.rs b/src/test/run-pass/issues/issue-26873-onefile.rs deleted file mode 100644 index f06c6499eb0..00000000000 --- a/src/test/run-pass/issues/issue-26873-onefile.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-26996.rs b/src/test/run-pass/issues/issue-26996.rs deleted file mode 100644 index 04382be27d7..00000000000 --- a/src/test/run-pass/issues/issue-26996.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27021.rs b/src/test/run-pass/issues/issue-27021.rs deleted file mode 100644 index 30551375450..00000000000 --- a/src/test/run-pass/issues/issue-27021.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs b/src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs deleted file mode 100644 index c6f925de5d7..00000000000 --- a/src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -fn main() { - let x = &mut 1; - assert_eq!(*x + { *x=2; 1 }, 2); -} diff --git a/src/test/run-pass/issues/issue-2708.rs b/src/test/run-pass/issues/issue-2708.rs deleted file mode 100644 index abd5e9507f8..00000000000 --- a/src/test/run-pass/issues/issue-2708.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2718.rs b/src/test/run-pass/issues/issue-2718.rs deleted file mode 100644 index 6449337eea4..00000000000 --- a/src/test/run-pass/issues/issue-2718.rs +++ /dev/null @@ -1,327 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2723-b.rs b/src/test/run-pass/issues/issue-2723-b.rs deleted file mode 100644 index 1910561d0ba..00000000000 --- a/src/test/run-pass/issues/issue-2723-b.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27240.rs b/src/test/run-pass/issues/issue-27240.rs deleted file mode 100644 index a22db76b9bc..00000000000 --- a/src/test/run-pass/issues/issue-27240.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27268.rs b/src/test/run-pass/issues/issue-27268.rs deleted file mode 100644 index 161e2d4d204..00000000000 --- a/src/test/run-pass/issues/issue-27268.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - const _C: &'static dyn Fn() = &||{}; -} diff --git a/src/test/run-pass/issues/issue-27320.rs b/src/test/run-pass/issues/issue-27320.rs deleted file mode 100644 index d1aa56b915b..00000000000 --- a/src/test/run-pass/issues/issue-27320.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2734.rs b/src/test/run-pass/issues/issue-2734.rs deleted file mode 100644 index d449f6449aa..00000000000 --- a/src/test/run-pass/issues/issue-2734.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2735-2.rs b/src/test/run-pass/issues/issue-2735-2.rs deleted file mode 100644 index 70ebce9d35a..00000000000 --- a/src/test/run-pass/issues/issue-2735-2.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2735-3.rs b/src/test/run-pass/issues/issue-2735-3.rs deleted file mode 100644 index 23301537835..00000000000 --- a/src/test/run-pass/issues/issue-2735-3.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2735.rs b/src/test/run-pass/issues/issue-2735.rs deleted file mode 100644 index 794c7d4edaa..00000000000 --- a/src/test/run-pass/issues/issue-2735.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27401-dropflag-reinit.rs b/src/test/run-pass/issues/issue-27401-dropflag-reinit.rs deleted file mode 100644 index e137575c2f8..00000000000 --- a/src/test/run-pass/issues/issue-27401-dropflag-reinit.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2748-b.rs b/src/test/run-pass/issues/issue-2748-b.rs deleted file mode 100644 index 8df735ac88e..00000000000 --- a/src/test/run-pass/issues/issue-2748-b.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27639.rs b/src/test/run-pass/issues/issue-27639.rs deleted file mode 100644 index 945fbad91f6..00000000000 --- a/src/test/run-pass/issues/issue-27639.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27859.rs b/src/test/run-pass/issues/issue-27859.rs deleted file mode 100644 index 259d706fa2a..00000000000 --- a/src/test/run-pass/issues/issue-27859.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27890.rs b/src/test/run-pass/issues/issue-27890.rs deleted file mode 100644 index 9f85473380f..00000000000 --- a/src/test/run-pass/issues/issue-27890.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27901.rs b/src/test/run-pass/issues/issue-27901.rs deleted file mode 100644 index ffd90b68983..00000000000 --- a/src/test/run-pass/issues/issue-27901.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27949.rs b/src/test/run-pass/issues/issue-27949.rs deleted file mode 100644 index e905da72aad..00000000000 --- a/src/test/run-pass/issues/issue-27949.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/issues/issue-27997.rs b/src/test/run-pass/issues/issue-27997.rs deleted file mode 100644 index dd74cf75249..00000000000 --- a/src/test/run-pass/issues/issue-27997.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28181.rs b/src/test/run-pass/issues/issue-28181.rs deleted file mode 100644 index c46e131c6ac..00000000000 --- a/src/test/run-pass/issues/issue-28181.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -fn bar(f: F) -> usize where F: Fn([usize; 1]) -> usize { f([2]) } - -fn main() { - bar(|u| { u[0] }); -} diff --git a/src/test/run-pass/issues/issue-28498-must-work-ex1.rs b/src/test/run-pass/issues/issue-28498-must-work-ex1.rs deleted file mode 100644 index 4699d3352ad..00000000000 --- a/src/test/run-pass/issues/issue-28498-must-work-ex1.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28498-must-work-ex2.rs b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs deleted file mode 100644 index cadf62461fd..00000000000 --- a/src/test/run-pass/issues/issue-28498-must-work-ex2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs deleted file mode 100644 index 90cf2cddcf0..00000000000 --- a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs deleted file mode 100644 index aea9fde5309..00000000000 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs deleted file mode 100644 index 91ef5a7c98d..00000000000 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs deleted file mode 100644 index 808f3b6e81e..00000000000 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28550.rs b/src/test/run-pass/issues/issue-28550.rs deleted file mode 100644 index 95583f80515..00000000000 --- a/src/test/run-pass/issues/issue-28550.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28676.rs b/src/test/run-pass/issues/issue-28676.rs deleted file mode 100644 index 2b83478ca61..00000000000 --- a/src/test/run-pass/issues/issue-28676.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28777.rs b/src/test/run-pass/issues/issue-28777.rs deleted file mode 100644 index 74de00adadb..00000000000 --- a/src/test/run-pass/issues/issue-28777.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -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/src/test/run-pass/issues/issue-28828.rs b/src/test/run-pass/issues/issue-28828.rs deleted file mode 100644 index 03968809eb7..00000000000 --- a/src/test/run-pass/issues/issue-28828.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28839.rs b/src/test/run-pass/issues/issue-28839.rs deleted file mode 100644 index 73be87a0c1e..00000000000 --- a/src/test/run-pass/issues/issue-28839.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2895.rs b/src/test/run-pass/issues/issue-2895.rs deleted file mode 100644 index d8c08996bc3..00000000000 --- a/src/test/run-pass/issues/issue-2895.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28950.rs b/src/test/run-pass/issues/issue-28950.rs deleted file mode 100644 index 8b55f42f3f4..00000000000 --- a/src/test/run-pass/issues/issue-28950.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-28983.rs b/src/test/run-pass/issues/issue-28983.rs deleted file mode 100644 index 3db26a1ee5f..00000000000 --- a/src/test/run-pass/issues/issue-28983.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29053.rs b/src/test/run-pass/issues/issue-29053.rs deleted file mode 100644 index 34c4a0f8f3e..00000000000 --- a/src/test/run-pass/issues/issue-29053.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29071-2.rs b/src/test/run-pass/issues/issue-29071-2.rs deleted file mode 100644 index f27bf0261db..00000000000 --- a/src/test/run-pass/issues/issue-29071-2.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29092.rs b/src/test/run-pass/issues/issue-29092.rs deleted file mode 100644 index f20d2a424b0..00000000000 --- a/src/test/run-pass/issues/issue-29092.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29166.rs b/src/test/run-pass/issues/issue-29166.rs deleted file mode 100644 index ca819ba39a2..00000000000 --- a/src/test/run-pass/issues/issue-29166.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29227.rs b/src/test/run-pass/issues/issue-29227.rs deleted file mode 100644 index e9dfc2840e5..00000000000 --- a/src/test/run-pass/issues/issue-29227.rs +++ /dev/null @@ -1,142 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2935.rs b/src/test/run-pass/issues/issue-2935.rs deleted file mode 100644 index 11641ca7380..00000000000 --- a/src/test/run-pass/issues/issue-2935.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2936.rs b/src/test/run-pass/issues/issue-2936.rs deleted file mode 100644 index 6b932d01d55..00000000000 --- a/src/test/run-pass/issues/issue-2936.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29466.rs b/src/test/run-pass/issues/issue-29466.rs deleted file mode 100644 index f8785a63217..00000000000 --- a/src/test/run-pass/issues/issue-29466.rs +++ /dev/null @@ -1,3603 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29485.rs b/src/test/run-pass/issues/issue-29485.rs deleted file mode 100644 index 6b2fb7126e3..00000000000 --- a/src/test/run-pass/issues/issue-29485.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29488.rs b/src/test/run-pass/issues/issue-29488.rs deleted file mode 100644 index 3c9a6a80dbf..00000000000 --- a/src/test/run-pass/issues/issue-29488.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29522.rs b/src/test/run-pass/issues/issue-29522.rs deleted file mode 100644 index 3d2de5ef63a..00000000000 --- a/src/test/run-pass/issues/issue-29522.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29663.rs b/src/test/run-pass/issues/issue-29663.rs deleted file mode 100644 index e2e89a8bfa3..00000000000 --- a/src/test/run-pass/issues/issue-29663.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29668.rs b/src/test/run-pass/issues/issue-29668.rs deleted file mode 100644 index 3d6c27bcda1..00000000000 --- a/src/test/run-pass/issues/issue-29668.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29746.rs b/src/test/run-pass/issues/issue-29746.rs deleted file mode 100644 index 428cc637f55..00000000000 --- a/src/test/run-pass/issues/issue-29746.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29844.rs b/src/test/run-pass/issues/issue-29844.rs deleted file mode 100644 index e08942da5e4..00000000000 --- a/src/test/run-pass/issues/issue-29844.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-2989.rs b/src/test/run-pass/issues/issue-2989.rs deleted file mode 100644 index c0b67374370..00000000000 --- a/src/test/run-pass/issues/issue-2989.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29914-2.rs b/src/test/run-pass/issues/issue-29914-2.rs deleted file mode 100644 index 626de269d95..00000000000 --- a/src/test/run-pass/issues/issue-29914-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -const ARR: [usize; 5] = [5, 4, 3, 2, 1]; - -fn main() { - assert_eq!(3, ARR[ARR[3]]); -} diff --git a/src/test/run-pass/issues/issue-29914-3.rs b/src/test/run-pass/issues/issue-29914-3.rs deleted file mode 100644 index 1c6c64eb316..00000000000 --- a/src/test/run-pass/issues/issue-29914-3.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29914.rs b/src/test/run-pass/issues/issue-29914.rs deleted file mode 100644 index 6da63664dfa..00000000000 --- a/src/test/run-pass/issues/issue-29914.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-29927-1.rs b/src/test/run-pass/issues/issue-29927-1.rs deleted file mode 100644 index a236e491375..00000000000 --- a/src/test/run-pass/issues/issue-29927-1.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] -const fn f() -> usize { - 5 -} -struct A { - field: usize, -} -fn main() { - let _ = [0; f()]; -} diff --git a/src/test/run-pass/issues/issue-29927.rs b/src/test/run-pass/issues/issue-29927.rs deleted file mode 100644 index 3385e4e6e94..00000000000 --- a/src/test/run-pass/issues/issue-29927.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] -struct A { - field: usize, -} -const fn f() -> usize { - 5 -} -fn main() { - let _ = [0; f()]; -} diff --git a/src/test/run-pass/issues/issue-29948.rs b/src/test/run-pass/issues/issue-29948.rs deleted file mode 100644 index 8ede8143ea6..00000000000 --- a/src/test/run-pass/issues/issue-29948.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30018-nopanic.rs b/src/test/run-pass/issues/issue-30018-nopanic.rs deleted file mode 100644 index 291bab2736d..00000000000 --- a/src/test/run-pass/issues/issue-30018-nopanic.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30018-panic.rs b/src/test/run-pass/issues/issue-30018-panic.rs deleted file mode 100644 index 50749b0c742..00000000000 --- a/src/test/run-pass/issues/issue-30018-panic.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30081.rs b/src/test/run-pass/issues/issue-30081.rs deleted file mode 100644 index e7fca96ed9e..00000000000 --- a/src/test/run-pass/issues/issue-30081.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3012-2.rs b/src/test/run-pass/issues/issue-3012-2.rs deleted file mode 100644 index 7d32c51f569..00000000000 --- a/src/test/run-pass/issues/issue-3012-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3026.rs b/src/test/run-pass/issues/issue-3026.rs deleted file mode 100644 index 1dea8134fba..00000000000 --- a/src/test/run-pass/issues/issue-3026.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3037.rs b/src/test/run-pass/issues/issue-3037.rs deleted file mode 100644 index ff4d32c2840..00000000000 --- a/src/test/run-pass/issues/issue-3037.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30371.rs b/src/test/run-pass/issues/issue-30371.rs deleted file mode 100644 index 58521b95cf6..00000000000 --- a/src/test/run-pass/issues/issue-30371.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30490.rs b/src/test/run-pass/issues/issue-30490.rs deleted file mode 100644 index 76e72246887..00000000000 --- a/src/test/run-pass/issues/issue-30490.rs +++ /dev/null @@ -1,102 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3052.rs b/src/test/run-pass/issues/issue-3052.rs deleted file mode 100644 index ee2456da3e2..00000000000 --- a/src/test/run-pass/issues/issue-3052.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30530.rs b/src/test/run-pass/issues/issue-30530.rs deleted file mode 100644 index 111fb8aa506..00000000000 --- a/src/test/run-pass/issues/issue-30530.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-30615.rs b/src/test/run-pass/issues/issue-30615.rs deleted file mode 100644 index c718449d84e..00000000000 --- a/src/test/run-pass/issues/issue-30615.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -fn main() { - &0u8 as *const u8 as *const dyn PartialEq; - &[0u8] as *const [u8; 1] as *const [u8]; -} diff --git a/src/test/run-pass/issues/issue-30756.rs b/src/test/run-pass/issues/issue-30756.rs deleted file mode 100644 index 836db951bb7..00000000000 --- a/src/test/run-pass/issues/issue-30756.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![forbid(unsafe_code)] - -thread_local!(static FOO: u8 = 1); - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-30891.rs b/src/test/run-pass/issues/issue-30891.rs deleted file mode 100644 index 30f55e0bd64..00000000000 --- a/src/test/run-pass/issues/issue-30891.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -const ERROR_CONST: bool = true; - -fn get() -> bool { - false || ERROR_CONST -} - -pub fn main() { - assert_eq!(get(), true); -} diff --git a/src/test/run-pass/issues/issue-3091.rs b/src/test/run-pass/issues/issue-3091.rs deleted file mode 100644 index 0c0a412420a..00000000000 --- a/src/test/run-pass/issues/issue-3091.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let x = 1; - let y = 1; - assert_eq!(&x, &y); -} diff --git a/src/test/run-pass/issues/issue-3109.rs b/src/test/run-pass/issues/issue-3109.rs deleted file mode 100644 index bd807cad753..00000000000 --- a/src/test/run-pass/issues/issue-3109.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -pub fn main() { - println!("{:?}", ("hi there!", "you")); -} diff --git a/src/test/run-pass/issues/issue-3121.rs b/src/test/run-pass/issues/issue-3121.rs deleted file mode 100644 index f7bbfa9f6f4..00000000000 --- a/src/test/run-pass/issues/issue-3121.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-31267-additional.rs b/src/test/run-pass/issues/issue-31267-additional.rs deleted file mode 100644 index 70dce2c9490..00000000000 --- a/src/test/run-pass/issues/issue-31267-additional.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-31267.rs b/src/test/run-pass/issues/issue-31267.rs deleted file mode 100644 index 50843c89eb4..00000000000 --- a/src/test/run-pass/issues/issue-31267.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-31299.rs b/src/test/run-pass/issues/issue-31299.rs deleted file mode 100644 index abed18d81f8..00000000000 --- a/src/test/run-pass/issues/issue-31299.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3136-b.rs b/src/test/run-pass/issues/issue-3136-b.rs deleted file mode 100644 index c4ca7236e76..00000000000 --- a/src/test/run-pass/issues/issue-3136-b.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-3136-a.rc - -// pretty-expanded FIXME #23616 - -extern crate issue_3136_a; - -pub fn main() {} diff --git a/src/test/run-pass/issues/issue-31702.rs b/src/test/run-pass/issues/issue-31702.rs deleted file mode 100644 index 5b24eead345..00000000000 --- a/src/test/run-pass/issues/issue-31702.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-31776.rs b/src/test/run-pass/issues/issue-31776.rs deleted file mode 100644 index c0d2c91e577..00000000000 --- a/src/test/run-pass/issues/issue-31776.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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) {} - } - } -} - -// ------------------------------------------------------ - -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 - } -} - -// ------------------------------------------------------ - -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/src/test/run-pass/issues/issue-32008.rs b/src/test/run-pass/issues/issue-32008.rs deleted file mode 100644 index 6c2e206796f..00000000000 --- a/src/test/run-pass/issues/issue-32008.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3211.rs b/src/test/run-pass/issues/issue-3211.rs deleted file mode 100644 index 49dd4fa7360..00000000000 --- a/src/test/run-pass/issues/issue-3211.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3220.rs b/src/test/run-pass/issues/issue-3220.rs deleted file mode 100644 index 7dc672edb54..00000000000 --- a/src/test/run-pass/issues/issue-3220.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-32292.rs b/src/test/run-pass/issues/issue-32292.rs deleted file mode 100644 index 99b865391de..00000000000 --- a/src/test/run-pass/issues/issue-32292.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![deny(warnings)] - -#[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] -struct Foo; - -fn main() { - let _ = Foo; -} diff --git a/src/test/run-pass/issues/issue-32389.rs b/src/test/run-pass/issues/issue-32389.rs deleted file mode 100644 index cc94cc819d6..00000000000 --- a/src/test/run-pass/issues/issue-32389.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-32518.rs b/src/test/run-pass/issues/issue-32518.rs deleted file mode 100644 index 808b40f71b3..00000000000 --- a/src/test/run-pass/issues/issue-32518.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-32805.rs b/src/test/run-pass/issues/issue-32805.rs deleted file mode 100644 index 23c19473903..00000000000 --- a/src/test/run-pass/issues/issue-32805.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3290.rs b/src/test/run-pass/issues/issue-3290.rs deleted file mode 100644 index 63e1b28a60a..00000000000 --- a/src/test/run-pass/issues/issue-3290.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let mut x: Box<_> = box 3; - x = x; - assert_eq!(*x, 3); -} diff --git a/src/test/run-pass/issues/issue-32947.rs b/src/test/run-pass/issues/issue-32947.rs deleted file mode 100644 index b07def21e88..00000000000 --- a/src/test/run-pass/issues/issue-32947.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33096.rs b/src/test/run-pass/issues/issue-33096.rs deleted file mode 100644 index f0b472e2fe8..00000000000 --- a/src/test/run-pass/issues/issue-33096.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -// compile-flags: -g - -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/src/test/run-pass/issues/issue-33185.rs b/src/test/run-pass/issues/issue-33185.rs deleted file mode 100644 index 0d6669146a6..00000000000 --- a/src/test/run-pass/issues/issue-33185.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33187.rs b/src/test/run-pass/issues/issue-33187.rs deleted file mode 100644 index 5226f9faf56..00000000000 --- a/src/test/run-pass/issues/issue-33187.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -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/src/test/run-pass/issues/issue-33202.rs b/src/test/run-pass/issues/issue-33202.rs deleted file mode 100644 index 11b89ae1b47..00000000000 --- a/src/test/run-pass/issues/issue-33202.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#[repr(C)] -pub enum CPOption { - PSome(T), -} - -fn main() { - println!("sizeof CPOption {}", std::mem::size_of::>()); -} diff --git a/src/test/run-pass/issues/issue-333.rs b/src/test/run-pass/issues/issue-333.rs deleted file mode 100644 index 0753aaa0797..00000000000 --- a/src/test/run-pass/issues/issue-333.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33387.rs b/src/test/run-pass/issues/issue-33387.rs deleted file mode 100644 index 499fa7c1f27..00000000000 --- a/src/test/run-pass/issues/issue-33387.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33461.rs b/src/test/run-pass/issues/issue-33461.rs deleted file mode 100644 index 4e01d4d3061..00000000000 --- a/src/test/run-pass/issues/issue-33461.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33498.rs b/src/test/run-pass/issues/issue-33498.rs deleted file mode 100644 index 9c8a97e7e6b..00000000000 --- a/src/test/run-pass/issues/issue-33498.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(unused_variables)] -pub fn main() { - let x = (0, 2); - - match x { - (0, ref y) => {} - (y, 0) => {} - _ => (), - } -} diff --git a/src/test/run-pass/issues/issue-33537.rs b/src/test/run-pass/issues/issue-33537.rs deleted file mode 100644 index 3539aa64776..00000000000 --- a/src/test/run-pass/issues/issue-33537.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33687.rs b/src/test/run-pass/issues/issue-33687.rs deleted file mode 100644 index ac802ed86dc..00000000000 --- a/src/test/run-pass/issues/issue-33687.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33770.rs b/src/test/run-pass/issues/issue-33770.rs deleted file mode 100644 index 39ae009c996..00000000000 --- a/src/test/run-pass/issues/issue-33770.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3389.rs b/src/test/run-pass/issues/issue-3389.rs deleted file mode 100644 index 294a07229fb..00000000000 --- a/src/test/run-pass/issues/issue-3389.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-33992.rs b/src/test/run-pass/issues/issue-33992.rs deleted file mode 100644 index 94fccff9fc6..00000000000 --- a/src/test/run-pass/issues/issue-33992.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -// ignore-windows -// ignore-macos -// ignore-wasm32-bare 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/src/test/run-pass/issues/issue-34053.rs b/src/test/run-pass/issues/issue-34053.rs deleted file mode 100644 index fa23ae8f95b..00000000000 --- a/src/test/run-pass/issues/issue-34053.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-34074.rs b/src/test/run-pass/issues/issue-34074.rs deleted file mode 100644 index 0600d3937c1..00000000000 --- a/src/test/run-pass/issues/issue-34074.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3429.rs b/src/test/run-pass/issues/issue-3429.rs deleted file mode 100644 index 9d94c3ff61c..00000000000 --- a/src/test/run-pass/issues/issue-3429.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - let x = 1_usize; - let y = || x; - let _z = y(); -} diff --git a/src/test/run-pass/issues/issue-34427.rs b/src/test/run-pass/issues/issue-34427.rs deleted file mode 100644 index a14b5b9e278..00000000000 --- a/src/test/run-pass/issues/issue-34427.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3447.rs b/src/test/run-pass/issues/issue-3447.rs deleted file mode 100644 index 1e329d1522a..00000000000 --- a/src/test/run-pass/issues/issue-3447.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-34503.rs b/src/test/run-pass/issues/issue-34503.rs deleted file mode 100644 index 26e7358408f..00000000000 --- a/src/test/run-pass/issues/issue-34503.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-34569.rs b/src/test/run-pass/issues/issue-34569.rs deleted file mode 100644 index 1f68560509e..00000000000 --- a/src/test/run-pass/issues/issue-34569.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// compile-flags:-g - -// 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/src/test/run-pass/issues/issue-34571.rs b/src/test/run-pass/issues/issue-34571.rs deleted file mode 100644 index bad1bebc697..00000000000 --- a/src/test/run-pass/issues/issue-34571.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#[repr(u8)] -enum Foo { - Foo(u8), -} - -fn main() { - match Foo::Foo(1) { - _ => () - } -} diff --git a/src/test/run-pass/issues/issue-34784.rs b/src/test/run-pass/issues/issue-34784.rs deleted file mode 100644 index d3206e99430..00000000000 --- a/src/test/run-pass/issues/issue-34784.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -#![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/src/test/run-pass/issues/issue-34796.rs b/src/test/run-pass/issues/issue-34796.rs deleted file mode 100644 index 88d5c50a27d..00000000000 --- a/src/test/run-pass/issues/issue-34796.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-34798.rs b/src/test/run-pass/issues/issue-34798.rs deleted file mode 100644 index f0d710123cd..00000000000 --- a/src/test/run-pass/issues/issue-34798.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-34932.rs b/src/test/run-pass/issues/issue-34932.rs deleted file mode 100644 index 3a5fd20ebc3..00000000000 --- a/src/test/run-pass/issues/issue-34932.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// compile-flags:--test -// rustc-env:RUSTC_BOOTSTRAP_KEY= -#![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/src/test/run-pass/issues/issue-3500.rs b/src/test/run-pass/issues/issue-3500.rs deleted file mode 100644 index 7b39cc16cab..00000000000 --- a/src/test/run-pass/issues/issue-3500.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - let x = &Some(1); - match x { - &Some(_) => (), - &None => (), - } -} diff --git a/src/test/run-pass/issues/issue-35423.rs b/src/test/run-pass/issues/issue-35423.rs deleted file mode 100644 index 202ffcc1d0d..00000000000 --- a/src/test/run-pass/issues/issue-35423.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3556.rs b/src/test/run-pass/issues/issue-3556.rs deleted file mode 100644 index 3c1934ade35..00000000000 --- a/src/test/run-pass/issues/issue-3556.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3559.rs b/src/test/run-pass/issues/issue-3559.rs deleted file mode 100644 index 9d498584a9d..00000000000 --- a/src/test/run-pass/issues/issue-3559.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-35600.rs b/src/test/run-pass/issues/issue-35600.rs deleted file mode 100644 index 9d74726d279..00000000000 --- a/src/test/run-pass/issues/issue-35600.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -#![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/src/test/run-pass/issues/issue-3563-3.rs b/src/test/run-pass/issues/issue-3563-3.rs deleted file mode 100644 index bedfdab97d5..00000000000 --- a/src/test/run-pass/issues/issue-3563-3.rs +++ /dev/null @@ -1,180 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3574.rs b/src/test/run-pass/issues/issue-3574.rs deleted file mode 100644 index eb967577ffb..00000000000 --- a/src/test/run-pass/issues/issue-3574.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-35815.rs b/src/test/run-pass/issues/issue-35815.rs deleted file mode 100644 index 05fd1b15d43..00000000000 --- a/src/test/run-pass/issues/issue-35815.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36023.rs b/src/test/run-pass/issues/issue-36023.rs deleted file mode 100644 index 64d92bf8c3c..00000000000 --- a/src/test/run-pass/issues/issue-36023.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36036-associated-type-layout.rs b/src/test/run-pass/issues/issue-36036-associated-type-layout.rs deleted file mode 100644 index 022f9a5d556..00000000000 --- a/src/test/run-pass/issues/issue-36036-associated-type-layout.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36053.rs b/src/test/run-pass/issues/issue-36053.rs deleted file mode 100644 index a61c02c0a12..00000000000 --- a/src/test/run-pass/issues/issue-36053.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs b/src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs deleted file mode 100644 index 2d49151ffcc..00000000000 --- a/src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36260.rs b/src/test/run-pass/issues/issue-36260.rs deleted file mode 100644 index d96dc80ea71..00000000000 --- a/src/test/run-pass/issues/issue-36260.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36278-prefix-nesting.rs b/src/test/run-pass/issues/issue-36278-prefix-nesting.rs deleted file mode 100644 index 62d1f5f8258..00000000000 --- a/src/test/run-pass/issues/issue-36278-prefix-nesting.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36381.rs b/src/test/run-pass/issues/issue-36381.rs deleted file mode 100644 index 7db56f1dce8..00000000000 --- a/src/test/run-pass/issues/issue-36381.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36401.rs b/src/test/run-pass/issues/issue-36401.rs deleted file mode 100644 index f51197b01c7..00000000000 --- a/src/test/run-pass/issues/issue-36401.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36474.rs b/src/test/run-pass/issues/issue-36474.rs deleted file mode 100644 index 90ee5b3cd4b..00000000000 --- a/src/test/run-pass/issues/issue-36474.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3656.rs b/src/test/run-pass/issues/issue-3656.rs deleted file mode 100644 index d55a22a72b6..00000000000 --- a/src/test/run-pass/issues/issue-3656.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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, uint32_t, c_void}; - -pub struct KEYGEN { - hash_algorithm: [c_uint; 2], - count: uint32_t, - salt: *const c_void, - salt_size: uint32_t, -} - -extern { - // Bogus signature, just need to test if it compiles. - pub fn malloc(data: KEYGEN); -} - -pub fn main() { -} diff --git a/src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs b/src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs deleted file mode 100644 index 34bbb66d979..00000000000 --- a/src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36768.rs b/src/test/run-pass/issues/issue-36768.rs deleted file mode 100644 index f671cbc8205..00000000000 --- a/src/test/run-pass/issues/issue-36768.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// compile-flags:--test -#![deny(private_in_public)] - -#[test] fn foo() {} -mod foo {} - -#[test] fn core() {} -extern crate core; diff --git a/src/test/run-pass/issues/issue-36786-resolve-call.rs b/src/test/run-pass/issues/issue-36786-resolve-call.rs deleted file mode 100644 index e5341ba7dbe..00000000000 --- a/src/test/run-pass/issues/issue-36786-resolve-call.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36792.rs b/src/test/run-pass/issues/issue-36792.rs deleted file mode 100644 index 99ae633dd0e..00000000000 --- a/src/test/run-pass/issues/issue-36792.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -fn foo() -> impl Copy { - foo -} -fn main() { - foo(); -} diff --git a/src/test/run-pass/issues/issue-36816.rs b/src/test/run-pass/issues/issue-36816.rs deleted file mode 100644 index 54690b43c46..00000000000 --- a/src/test/run-pass/issues/issue-36816.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -macro_rules! m { () => { 1 } } -macro_rules! n { () => { 1 + m!() } } - -fn main() { - let _: [u32; n!()] = [0, 0]; -} diff --git a/src/test/run-pass/issues/issue-3683.rs b/src/test/run-pass/issues/issue-3683.rs deleted file mode 100644 index b12c450c937..00000000000 --- a/src/test/run-pass/issues/issue-3683.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36856.rs b/src/test/run-pass/issues/issue-36856.rs deleted file mode 100644 index f2dfaf3dd36..00000000000 --- a/src/test/run-pass/issues/issue-36856.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// Regression test for #36856. - -// compile-flags:-g - -fn g() -> bool { - false -} - -pub fn main() { - let a = !g(); - if a != !g() { - panic!(); - } -} diff --git a/src/test/run-pass/issues/issue-36936.rs b/src/test/run-pass/issues/issue-36936.rs deleted file mode 100644 index 486a422b754..00000000000 --- a/src/test/run-pass/issues/issue-36936.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-36954.rs b/src/test/run-pass/issues/issue-36954.rs deleted file mode 100644 index 56ff9926ef1..00000000000 --- a/src/test/run-pass/issues/issue-36954.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-36954.rs - -extern crate issue_36954 as lib; - -fn main() { - let _ = lib::FOO; -} diff --git a/src/test/run-pass/issues/issue-3702.rs b/src/test/run-pass/issues/issue-3702.rs deleted file mode 100644 index f48d549b3eb..00000000000 --- a/src/test/run-pass/issues/issue-3702.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-37109.rs b/src/test/run-pass/issues/issue-37109.rs deleted file mode 100644 index 1e57d5f95e8..00000000000 --- a/src/test/run-pass/issues/issue-37109.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-37175.rs b/src/test/run-pass/issues/issue-37175.rs deleted file mode 100644 index 9ec9d48d18b..00000000000 --- a/src/test/run-pass/issues/issue-37175.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -macro_rules! m { (<$t:ty>) => { stringify!($t) } } -fn main() { - println!("{}", m!(>)); -} diff --git a/src/test/run-pass/issues/issue-37222.rs b/src/test/run-pass/issues/issue-37222.rs deleted file mode 100644 index 8ea5f6b7a27..00000000000 --- a/src/test/run-pass/issues/issue-37222.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-37291/auxiliary/lib.rs b/src/test/run-pass/issues/issue-37291/auxiliary/lib.rs deleted file mode 100644 index 1b163ee1391..00000000000 --- a/src/test/run-pass/issues/issue-37291/auxiliary/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![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/src/test/run-pass/issues/issue-37291/main.rs b/src/test/run-pass/issues/issue-37291/main.rs deleted file mode 100644 index 6fb6b50da20..00000000000 --- a/src/test/run-pass/issues/issue-37291/main.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3743.rs b/src/test/run-pass/issues/issue-3743.rs deleted file mode 100644 index 07741914f80..00000000000 --- a/src/test/run-pass/issues/issue-3743.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3753.rs b/src/test/run-pass/issues/issue-3753.rs deleted file mode 100644 index dc9e42bad97..00000000000 --- a/src/test/run-pass/issues/issue-3753.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-37686.rs b/src/test/run-pass/issues/issue-37686.rs deleted file mode 100644 index 8c376251449..00000000000 --- a/src/test/run-pass/issues/issue-37686.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -fn main() { - match (0, 0) { - (std::usize::MIN, std::usize::MAX) => {} - _ => {} - } -} diff --git a/src/test/run-pass/issues/issue-3794.rs b/src/test/run-pass/issues/issue-3794.rs deleted file mode 100644 index 408d8d866d8..00000000000 --- a/src/test/run-pass/issues/issue-3794.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-37991.rs b/src/test/run-pass/issues/issue-37991.rs deleted file mode 100644 index a6ac4d5ca2e..00000000000 --- a/src/test/run-pass/issues/issue-37991.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38002.rs b/src/test/run-pass/issues/issue-38002.rs deleted file mode 100644 index fdb31fc44a1..00000000000 --- a/src/test/run-pass/issues/issue-38002.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38033.rs b/src/test/run-pass/issues/issue-38033.rs deleted file mode 100644 index 16b867ec88f..00000000000 --- a/src/test/run-pass/issues/issue-38033.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38074.rs b/src/test/run-pass/issues/issue-38074.rs deleted file mode 100644 index 214d6752cef..00000000000 --- a/src/test/run-pass/issues/issue-38074.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38091.rs b/src/test/run-pass/issues/issue-38091.rs deleted file mode 100644 index 00aa810f830..00000000000 --- a/src/test/run-pass/issues/issue-38091.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -#![feature(specialization)] - -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 {} - -fn main() { - Iterate::iterate(0); -} diff --git a/src/test/run-pass/issues/issue-38190.rs b/src/test/run-pass/issues/issue-38190.rs deleted file mode 100644 index cfa0420c80d..00000000000 --- a/src/test/run-pass/issues/issue-38190.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38226.rs b/src/test/run-pass/issues/issue-38226.rs deleted file mode 100644 index 3213e3618a8..00000000000 --- a/src/test/run-pass/issues/issue-38226.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38437.rs b/src/test/run-pass/issues/issue-38437.rs deleted file mode 100644 index e1412169065..00000000000 --- a/src/test/run-pass/issues/issue-38437.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3847.rs b/src/test/run-pass/issues/issue-3847.rs deleted file mode 100644 index 16e0b00b39a..00000000000 --- a/src/test/run-pass/issues/issue-3847.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38556.rs b/src/test/run-pass/issues/issue-38556.rs deleted file mode 100644 index 63fd9db08ff..00000000000 --- a/src/test/run-pass/issues/issue-38556.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![allow(dead_code)] -pub struct Foo; - -macro_rules! reexport { - () => { use Foo as Bar; } -} - -reexport!(); - -fn main() { - fn f(_: Bar) {} -} diff --git a/src/test/run-pass/issues/issue-38763.rs b/src/test/run-pass/issues/issue-38763.rs deleted file mode 100644 index 6e6de09225f..00000000000 --- a/src/test/run-pass/issues/issue-38763.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// ignore-emscripten - -#[repr(C)] -pub struct Foo(i128); - -#[no_mangle] -pub extern "C" fn foo(x: Foo) -> Foo { x } - -fn main() { - foo(Foo(1)); -} diff --git a/src/test/run-pass/issues/issue-3878.rs b/src/test/run-pass/issues/issue-3878.rs deleted file mode 100644 index a121f0ba878..00000000000 --- a/src/test/run-pass/issues/issue-3878.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![allow(path_statements)] -#![feature(box_syntax)] - -pub fn main() { - let y: Box<_> = box 1; - y; -} diff --git a/src/test/run-pass/issues/issue-38942.rs b/src/test/run-pass/issues/issue-38942.rs deleted file mode 100644 index 308bdd6e28c..00000000000 --- a/src/test/run-pass/issues/issue-38942.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3895.rs b/src/test/run-pass/issues/issue-3895.rs deleted file mode 100644 index c560ca60dd3..00000000000 --- a/src/test/run-pass/issues/issue-3895.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-38987.rs b/src/test/run-pass/issues/issue-38987.rs deleted file mode 100644 index cb4e1b0d409..00000000000 --- a/src/test/run-pass/issues/issue-38987.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; -} diff --git a/src/test/run-pass/issues/issue-3904.rs b/src/test/run-pass/issues/issue-3904.rs deleted file mode 100644 index 7beb91a28d2..00000000000 --- a/src/test/run-pass/issues/issue-3904.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39292.rs b/src/test/run-pass/issues/issue-39292.rs deleted file mode 100644 index 968cf08916f..00000000000 --- a/src/test/run-pass/issues/issue-39292.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3935.rs b/src/test/run-pass/issues/issue-3935.rs deleted file mode 100644 index e98d68e0eb2..00000000000 --- a/src/test/run-pass/issues/issue-3935.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39367.rs b/src/test/run-pass/issues/issue-39367.rs deleted file mode 100644 index 8314be3d14c..00000000000 --- a/src/test/run-pass/issues/issue-39367.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39548.rs b/src/test/run-pass/issues/issue-39548.rs deleted file mode 100644 index 304e37bf3d6..00000000000 --- a/src/test/run-pass/issues/issue-39548.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -type Array = [(); ((1 < 2) == false) as usize]; - -fn main() { - let _: Array = []; -} diff --git a/src/test/run-pass/issues/issue-39709.rs b/src/test/run-pass/issues/issue-39709.rs deleted file mode 100644 index 69ef2700ef3..00000000000 --- a/src/test/run-pass/issues/issue-39709.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -#![allow(unused_macros)] -fn main() { - println!("{}", { macro_rules! x { ($(t:tt)*) => {} } 33 }); -} diff --git a/src/test/run-pass/issues/issue-39720.rs b/src/test/run-pass/issues/issue-39720.rs deleted file mode 100644 index a3baa361d57..00000000000 --- a/src/test/run-pass/issues/issue-39720.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(non_snake_case)] - -// ignore-emscripten FIXME(#45351) - -#![feature(repr_simd, platform_intrinsics)] - -#[repr(C)] -#[repr(simd)] -#[derive(Copy, Clone, Debug)] -pub struct char3(pub i8, pub i8, pub i8); - -#[repr(C)] -#[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/src/test/run-pass/issues/issue-39720.stderr b/src/test/run-pass/issues/issue-39720.stderr deleted file mode 100644 index 8121ed28940..00000000000 --- a/src/test/run-pass/issues/issue-39720.stderr +++ /dev/null @@ -1,16 +0,0 @@ -warning[E0566]: conflicting representation hints - --> $DIR/issue-39720.rs:8:8 - | -LL | #[repr(C)] - | ^ -LL | #[repr(simd)] - | ^^^^ - -warning[E0566]: conflicting representation hints - --> $DIR/issue-39720.rs:13:8 - | -LL | #[repr(C)] - | ^ -LL | #[repr(simd)] - | ^^^^ - diff --git a/src/test/run-pass/issues/issue-3979-generics.rs b/src/test/run-pass/issues/issue-3979-generics.rs deleted file mode 100644 index 519de1cad6e..00000000000 --- a/src/test/run-pass/issues/issue-3979-generics.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3979-xcrate.rs b/src/test/run-pass/issues/issue-3979-xcrate.rs deleted file mode 100644 index fcb1f55c32f..00000000000 --- a/src/test/run-pass/issues/issue-3979-xcrate.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-3979.rs b/src/test/run-pass/issues/issue-3979.rs deleted file mode 100644 index 72949d8c757..00000000000 --- a/src/test/run-pass/issues/issue-3979.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39808.rs b/src/test/run-pass/issues/issue-39808.rs deleted file mode 100644 index a4701367373..00000000000 --- a/src/test/run-pass/issues/issue-39808.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39823.rs b/src/test/run-pass/issues/issue-39823.rs deleted file mode 100644 index 148cf527e7c..00000000000 --- a/src/test/run-pass/issues/issue-39823.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-39827.rs b/src/test/run-pass/issues/issue-39827.rs deleted file mode 100644 index 782c668c843..00000000000 --- a/src/test/run-pass/issues/issue-39827.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-40003.rs b/src/test/run-pass/issues/issue-40003.rs deleted file mode 100644 index 642de6b8fe3..00000000000 --- a/src/test/run-pass/issues/issue-40003.rs +++ /dev/null @@ -1,178 +0,0 @@ -// 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/src/test/run-pass/issues/issue-40085.rs b/src/test/run-pass/issues/issue-40085.rs deleted file mode 100644 index 132044cfd6d..00000000000 --- a/src/test/run-pass/issues/issue-40085.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-40235.rs b/src/test/run-pass/issues/issue-40235.rs deleted file mode 100644 index 0f799c3503f..00000000000 --- a/src/test/run-pass/issues/issue-40235.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unused_variables)] -fn foo() {} - -fn main() { - while let Some(foo) = Some(1) { break } - foo(); -} diff --git a/src/test/run-pass/issues/issue-40408.rs b/src/test/run-pass/issues/issue-40408.rs deleted file mode 100644 index 81acc41cb83..00000000000 --- a/src/test/run-pass/issues/issue-40408.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -fn main() { - println!("{}", 0E+10); - println!("{}", 0e+10); - println!("{}", 00e+10); - println!("{}", 00E+10); -} diff --git a/src/test/run-pass/issues/issue-40469.rs b/src/test/run-pass/issues/issue-40469.rs deleted file mode 100644 index 25e08ef85e9..00000000000 --- a/src/test/run-pass/issues/issue-40469.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// ignore-pretty issue #37195 - -#![allow(dead_code)] - -include!("auxiliary/issue-40469.rs"); -fn f() { m!(); } - -fn main() {} diff --git a/src/test/run-pass/issues/issue-40770.rs b/src/test/run-pass/issues/issue-40770.rs deleted file mode 100644 index c9713c15798..00000000000 --- a/src/test/run-pass/issues/issue-40770.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(unused_macros)] -macro_rules! m { - ($e:expr) => { - macro_rules! n { () => { $e } } - } -} - -fn main() { - m!(foo!()); -} diff --git a/src/test/run-pass/issues/issue-40847.rs b/src/test/run-pass/issues/issue-40847.rs deleted file mode 100644 index 087b40ad6cd..00000000000 --- a/src/test/run-pass/issues/issue-40847.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-40883.rs b/src/test/run-pass/issues/issue-40883.rs deleted file mode 100644 index 37e61b1b0e6..00000000000 --- a/src/test/run-pass/issues/issue-40883.rs +++ /dev/null @@ -1,93 +0,0 @@ -// 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` + 128 "misc" bytes. - if stack_usage > mem::size_of::() * 2 + 128 { - 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/src/test/run-pass/issues/issue-40951.rs b/src/test/run-pass/issues/issue-40951.rs deleted file mode 100644 index 49171eba6b3..00000000000 --- a/src/test/run-pass/issues/issue-40951.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41053.rs b/src/test/run-pass/issues/issue-41053.rs deleted file mode 100644 index 967edfd4415..00000000000 --- a/src/test/run-pass/issues/issue-41053.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4107.rs b/src/test/run-pass/issues/issue-4107.rs deleted file mode 100644 index 98433e806e3..00000000000 --- a/src/test/run-pass/issues/issue-4107.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41213.rs b/src/test/run-pass/issues/issue-41213.rs deleted file mode 100644 index 5c91bf71102..00000000000 --- a/src/test/run-pass/issues/issue-41213.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41479.rs b/src/test/run-pass/issues/issue-41479.rs deleted file mode 100644 index 6daaf440e4b..00000000000 --- a/src/test/run-pass/issues/issue-41479.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -fn split(pair: (A, B)) { - let _a = pair.0; - let _b = pair.1; -} - -fn main() { - split(((), ((), ()))); -} diff --git a/src/test/run-pass/issues/issue-41498.rs b/src/test/run-pass/issues/issue-41498.rs deleted file mode 100644 index ad918ecddeb..00000000000 --- a/src/test/run-pass/issues/issue-41498.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41604.rs b/src/test/run-pass/issues/issue-41604.rs deleted file mode 100644 index 11a1cc25b71..00000000000 --- a/src/test/run-pass/issues/issue-41604.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -struct B; - -impl B { - fn init(&mut self) {} -} - -fn main() { - let mut b = [B]; - b[1-1].init(); -} diff --git a/src/test/run-pass/issues/issue-41677.rs b/src/test/run-pass/issues/issue-41677.rs deleted file mode 100644 index afddbc799b7..00000000000 --- a/src/test/run-pass/issues/issue-41677.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41696.rs b/src/test/run-pass/issues/issue-41696.rs deleted file mode 100644 index d094f71942f..00000000000 --- a/src/test/run-pass/issues/issue-41696.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41744.rs b/src/test/run-pass/issues/issue-41744.rs deleted file mode 100644 index dcdd1c21ee5..00000000000 --- a/src/test/run-pass/issues/issue-41744.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -trait Tc {} -impl Tc for bool {} - -fn main() { - let _: &[&dyn Tc] = &[&true]; -} diff --git a/src/test/run-pass/issues/issue-41803.rs b/src/test/run-pass/issues/issue-41803.rs deleted file mode 100644 index 19ab81d04d0..00000000000 --- a/src/test/run-pass/issues/issue-41803.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41849-variance-req.rs b/src/test/run-pass/issues/issue-41849-variance-req.rs deleted file mode 100644 index af081083a35..00000000000 --- a/src/test/run-pass/issues/issue-41849-variance-req.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/issues/issue-41888.rs b/src/test/run-pass/issues/issue-41888.rs deleted file mode 100644 index 32df520f279..00000000000 --- a/src/test/run-pass/issues/issue-41888.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42007.rs b/src/test/run-pass/issues/issue-42007.rs deleted file mode 100644 index a477e476eb9..00000000000 --- a/src/test/run-pass/issues/issue-42007.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4208.rs b/src/test/run-pass/issues/issue-4208.rs deleted file mode 100644 index 3b01811a9e8..00000000000 --- a/src/test/run-pass/issues/issue-4208.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42148.rs b/src/test/run-pass/issues/issue-42148.rs deleted file mode 100644 index cb8c0d6edb6..00000000000 --- a/src/test/run-pass/issues/issue-42148.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -struct Zst; - -fn main() { - unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) } -} diff --git a/src/test/run-pass/issues/issue-42210.rs b/src/test/run-pass/issues/issue-42210.rs deleted file mode 100644 index 318e3099f98..00000000000 --- a/src/test/run-pass/issues/issue-42210.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -// Regression test for #42210. - -// compile-flags: -g - -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/src/test/run-pass/issues/issue-4228.rs b/src/test/run-pass/issues/issue-4228.rs deleted file mode 100644 index 491000b6510..00000000000 --- a/src/test/run-pass/issues/issue-4228.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42453.rs b/src/test/run-pass/issues/issue-42453.rs deleted file mode 100644 index 92fefceabc1..00000000000 --- a/src/test/run-pass/issues/issue-42453.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -#[derive(Debug)] -struct builder; - -fn main() { - -} diff --git a/src/test/run-pass/issues/issue-42463.rs b/src/test/run-pass/issues/issue-42463.rs deleted file mode 100644 index 51d6ea3f7a8..00000000000 --- a/src/test/run-pass/issues/issue-42463.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4252.rs b/src/test/run-pass/issues/issue-4252.rs deleted file mode 100644 index 48e617fd7eb..00000000000 --- a/src/test/run-pass/issues/issue-4252.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42552.rs b/src/test/run-pass/issues/issue-42552.rs deleted file mode 100644 index 50d28a2f0c6..00000000000 --- a/src/test/run-pass/issues/issue-42552.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42679.rs b/src/test/run-pass/issues/issue-42679.rs deleted file mode 100644 index 596309f2568..00000000000 --- a/src/test/run-pass/issues/issue-42679.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-42747.rs b/src/test/run-pass/issues/issue-42747.rs deleted file mode 100644 index fec65878210..00000000000 --- a/src/test/run-pass/issues/issue-42747.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-43132.rs b/src/test/run-pass/issues/issue-43132.rs deleted file mode 100644 index c886f4b0a2d..00000000000 --- a/src/test/run-pass/issues/issue-43132.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/issues/issue-43205.rs b/src/test/run-pass/issues/issue-43205.rs deleted file mode 100644 index 894a61f3eff..00000000000 --- a/src/test/run-pass/issues/issue-43205.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass -fn main() { - &&[()][0]; - println!("{:?}", &[(),()][1]); -} diff --git a/src/test/run-pass/issues/issue-43291.rs b/src/test/run-pass/issues/issue-43291.rs deleted file mode 100644 index 52b629e35c8..00000000000 --- a/src/test/run-pass/issues/issue-43291.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4333.rs b/src/test/run-pass/issues/issue-4333.rs deleted file mode 100644 index 3df319b683f..00000000000 --- a/src/test/run-pass/issues/issue-4333.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-43692.rs b/src/test/run-pass/issues/issue-43692.rs deleted file mode 100644 index a9999c22651..00000000000 --- a/src/test/run-pass/issues/issue-43692.rs +++ /dev/null @@ -1,5 +0,0 @@ -// 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/src/test/run-pass/issues/issue-43853.rs b/src/test/run-pass/issues/issue-43853.rs deleted file mode 100644 index 47c3ab59aa2..00000000000 --- a/src/test/run-pass/issues/issue-43853.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4387.rs b/src/test/run-pass/issues/issue-4387.rs deleted file mode 100644 index 84592f16a4c..00000000000 --- a/src/test/run-pass/issues/issue-4387.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - let _foo = [0; 2*4]; -} diff --git a/src/test/run-pass/issues/issue-43910.rs b/src/test/run-pass/issues/issue-43910.rs deleted file mode 100644 index d8c87732930..00000000000 --- a/src/test/run-pass/issues/issue-43910.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![deny(unused_variables)] - -fn main() { - #[allow(unused_variables)] - let x = 12; -} diff --git a/src/test/run-pass/issues/issue-43923.rs b/src/test/run-pass/issues/issue-43923.rs deleted file mode 100644 index ad35a668554..00000000000 --- a/src/test/run-pass/issues/issue-43923.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4401.rs b/src/test/run-pass/issues/issue-4401.rs deleted file mode 100644 index fef73fbe1f5..00000000000 --- a/src/test/run-pass/issues/issue-4401.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-44333.rs b/src/test/run-pass/issues/issue-44333.rs deleted file mode 100644 index fffef975043..00000000000 --- a/src/test/run-pass/issues/issue-44333.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -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"), - BAR => println!("bar"), - _ => unreachable!(), - } -} diff --git a/src/test/run-pass/issues/issue-4446.rs b/src/test/run-pass/issues/issue-4446.rs deleted file mode 100644 index 948f2a7bdf3..00000000000 --- a/src/test/run-pass/issues/issue-4446.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4448.rs b/src/test/run-pass/issues/issue-4448.rs deleted file mode 100644 index 27d0326891b..00000000000 --- a/src/test/run-pass/issues/issue-4448.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-45124.rs b/src/test/run-pass/issues/issue-45124.rs deleted file mode 100644 index 942014c9184..00000000000 --- a/src/test/run-pass/issues/issue-45124.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-45152.rs b/src/test/run-pass/issues/issue-45152.rs deleted file mode 100644 index fb1c9fb78f3..00000000000 --- a/src/test/run-pass/issues/issue-45152.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4541.rs b/src/test/run-pass/issues/issue-4541.rs deleted file mode 100644 index 1f871fcf613..00000000000 --- a/src/test/run-pass/issues/issue-4541.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4542.rs b/src/test/run-pass/issues/issue-4542.rs deleted file mode 100644 index 24752114e9f..00000000000 --- a/src/test/run-pass/issues/issue-4542.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4545.rs b/src/test/run-pass/issues/issue-4545.rs deleted file mode 100644 index 86fcf9af21f..00000000000 --- a/src/test/run-pass/issues/issue-4545.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/issues/issue-45510.rs b/src/test/run-pass/issues/issue-45510.rs deleted file mode 100644 index 9e104ce6c4f..00000000000 --- a/src/test/run-pass/issues/issue-45510.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-45731.rs b/src/test/run-pass/issues/issue-45731.rs deleted file mode 100644 index d20c07276a8..00000000000 --- a/src/test/run-pass/issues/issue-45731.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// compile-flags:--test -g - -#[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/src/test/run-pass/issues/issue-46069.rs b/src/test/run-pass/issues/issue-46069.rs deleted file mode 100644 index 1d4f789828d..00000000000 --- a/src/test/run-pass/issues/issue-46069.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-46095.rs b/src/test/run-pass/issues/issue-46095.rs deleted file mode 100644 index 59ddb60c9f2..00000000000 --- a/src/test/run-pass/issues/issue-46095.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-46519.rs b/src/test/run-pass/issues/issue-46519.rs deleted file mode 100644 index 461ea2498b0..00000000000 --- a/src/test/run-pass/issues/issue-46519.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// compile-flags:--test -O - -#[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/src/test/run-pass/issues/issue-46553.rs b/src/test/run-pass/issues/issue-46553.rs deleted file mode 100644 index e21a532effd..00000000000 --- a/src/test/run-pass/issues/issue-46553.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -#![feature(const_fn)] -#![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/src/test/run-pass/issues/issue-46845.rs b/src/test/run-pass/issues/issue-46845.rs deleted file mode 100644 index fc85b25519a..00000000000 --- a/src/test/run-pass/issues/issue-46845.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-46855.rs b/src/test/run-pass/issues/issue-46855.rs deleted file mode 100644 index aa6378f8594..00000000000 --- a/src/test/run-pass/issues/issue-46855.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-46920-byte-array-patterns.rs b/src/test/run-pass/issues/issue-46920-byte-array-patterns.rs deleted file mode 100644 index 2a8b4bb4922..00000000000 --- a/src/test/run-pass/issues/issue-46920-byte-array-patterns.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-47139-1.rs b/src/test/run-pass/issues/issue-47139-1.rs deleted file mode 100644 index c55fc34346c..00000000000 --- a/src/test/run-pass/issues/issue-47139-1.rs +++ /dev/null @@ -1,78 +0,0 @@ -// run-pass -// Regression test for issue #47139: -// -// Coherence was encountering an (unnecessary) overflow trying to -// decide if the two impls of dummy overlap. -// -// The overflow went something like: -// -// - `&'a ?T: Insertable` ? -// - let ?T = Option ? -// - `Option: Insertable` ? -// - `Option<&'a ?U>: Insertable` ? -// - `&'a ?U: Insertable` ? -// -// While somewhere in the middle, a projection would occur, which -// broke cycle detection. -// -// It turned out that this cycle was being kicked off due to some -// extended diagnostic attempts in coherence, so removing those -// sidestepped the issue for now. - -#![allow(dead_code)] - -pub trait Insertable { - type Values; - - fn values(self) -> Self::Values; -} - -impl Insertable for Option - where - T: Insertable, - T::Values: Default, -{ - type Values = T::Values; - - fn values(self) -> Self::Values { - self.map(Insertable::values).unwrap_or_default() - } -} - -impl<'a, T> Insertable for &'a Option - where - Option<&'a T>: Insertable, -{ - type Values = as Insertable>::Values; - - fn values(self) -> Self::Values { - self.as_ref().values() - } -} - -impl<'a, T> Insertable for &'a [T] -{ - type Values = Self; - - fn values(self) -> Self::Values { - self - } -} - -trait Unimplemented { } - -trait Dummy { } - -struct Foo { t: T } - -impl<'a, U> Dummy for Foo<&'a U> - where &'a U: Insertable -{ -} - -impl Dummy for T - where T: Unimplemented -{ } - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-47139-2.rs b/src/test/run-pass/issues/issue-47139-2.rs deleted file mode 100644 index d2ef8942530..00000000000 --- a/src/test/run-pass/issues/issue-47139-2.rs +++ /dev/null @@ -1,66 +0,0 @@ -// run-pass -// Regression test for issue #47139: -// -// Same as issue-47139-1.rs, but the impls of dummy are in the -// opposite order. This influenced the way that coherence ran and in -// some cases caused the overflow to occur when it wouldn't otherwise. -// In an effort to make the regr test more robust, I am including both -// orderings. - -#![allow(dead_code)] - -pub trait Insertable { - type Values; - - fn values(self) -> Self::Values; -} - -impl Insertable for Option - where - T: Insertable, - T::Values: Default, -{ - type Values = T::Values; - - fn values(self) -> Self::Values { - self.map(Insertable::values).unwrap_or_default() - } -} - -impl<'a, T> Insertable for &'a Option - where - Option<&'a T>: Insertable, -{ - type Values = as Insertable>::Values; - - fn values(self) -> Self::Values { - self.as_ref().values() - } -} - -impl<'a, T> Insertable for &'a [T] -{ - type Values = Self; - - fn values(self) -> Self::Values { - self - } -} - -trait Unimplemented { } - -trait Dummy { } - -struct Foo { t: T } - -impl Dummy for T - where T: Unimplemented -{ } - -impl<'a, U> Dummy for Foo<&'a U> - where &'a U: Insertable -{ -} - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-4734.rs b/src/test/run-pass/issues/issue-4734.rs deleted file mode 100644 index 29c965d7ff5..00000000000 --- a/src/test/run-pass/issues/issue-4734.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4735.rs b/src/test/run-pass/issues/issue-4735.rs deleted file mode 100644 index 3ea4b01cd2b..00000000000 --- a/src/test/run-pass/issues/issue-4735.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-47364.rs b/src/test/run-pass/issues/issue-47364.rs deleted file mode 100644 index b524354d9a1..00000000000 --- a/src/test/run-pass/issues/issue-47364.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4759-1.rs b/src/test/run-pass/issues/issue-4759-1.rs deleted file mode 100644 index 96fae0fecd9..00000000000 --- a/src/test/run-pass/issues/issue-4759-1.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -trait U { fn f(self); } -impl U for isize { fn f(self) {} } -pub fn main() { 4.f(); } diff --git a/src/test/run-pass/issues/issue-4759.rs b/src/test/run-pass/issues/issue-4759.rs deleted file mode 100644 index 53785af0962..00000000000 --- a/src/test/run-pass/issues/issue-4759.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-47638.rs b/src/test/run-pass/issues/issue-47638.rs deleted file mode 100644 index a1ed3c36544..00000000000 --- a/src/test/run-pass/issues/issue-47638.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-48006.rs b/src/test/run-pass/issues/issue-48006.rs deleted file mode 100644 index 3a862ace55e..00000000000 --- a/src/test/run-pass/issues/issue-48006.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-48159.rs b/src/test/run-pass/issues/issue-48159.rs deleted file mode 100644 index fc8f31fb1ef..00000000000 --- a/src/test/run-pass/issues/issue-48159.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-48508-aux.rs b/src/test/run-pass/issues/issue-48508-aux.rs deleted file mode 100644 index ebdc70a04df..00000000000 --- a/src/test/run-pass/issues/issue-48508-aux.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// ignore-test Not a test. Used by issue-48508.rs - -pub fn other() -> f64 { - let µ = 1.0; - µ -} diff --git a/src/test/run-pass/issues/issue-48508.rs b/src/test/run-pass/issues/issue-48508.rs deleted file mode 100644 index 385192b882b..00000000000 --- a/src/test/run-pass/issues/issue-48508.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 - -#![feature(non_ascii_idents)] - -#[path = "issue-48508-aux.rs"] -mod other_file; - -fn main() { - other_file::other(); -} diff --git a/src/test/run-pass/issues/issue-4865-1.rs b/src/test/run-pass/issues/issue-4865-1.rs deleted file mode 100644 index 68fbee37d01..00000000000 --- a/src/test/run-pass/issues/issue-4865-1.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4865-2.rs b/src/test/run-pass/issues/issue-4865-2.rs deleted file mode 100644 index cbe1d0d32c6..00000000000 --- a/src/test/run-pass/issues/issue-4865-2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4865-3.rs b/src/test/run-pass/issues/issue-4865-3.rs deleted file mode 100644 index 12f9bba18d8..00000000000 --- a/src/test/run-pass/issues/issue-4865-3.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-4875.rs b/src/test/run-pass/issues/issue-4875.rs deleted file mode 100644 index 8d361314f73..00000000000 --- a/src/test/run-pass/issues/issue-4875.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-48962.rs b/src/test/run-pass/issues/issue-48962.rs deleted file mode 100644 index 80d815379be..00000000000 --- a/src/test/run-pass/issues/issue-48962.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-48984.rs b/src/test/run-pass/issues/issue-48984.rs deleted file mode 100644 index cb340f84897..00000000000 --- a/src/test/run-pass/issues/issue-48984.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49298.rs b/src/test/run-pass/issues/issue-49298.rs deleted file mode 100644 index 697a160b4ec..00000000000 --- a/src/test/run-pass/issues/issue-49298.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs deleted file mode 100644 index f30d7e2edcc..00000000000 --- a/src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49632.rs b/src/test/run-pass/issues/issue-49632.rs deleted file mode 100644 index 155fd0d24eb..00000000000 --- a/src/test/run-pass/issues/issue-49632.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(stmt_expr_attributes)] - -pub fn main() { - let _x = #[inline(always)] || {}; - let _y = #[inline(never)] || {}; - let _z = #[inline] || {}; -} diff --git a/src/test/run-pass/issues/issue-49685.rs b/src/test/run-pass/issues/issue-49685.rs deleted file mode 100644 index fb328d67b75..00000000000 --- a/src/test/run-pass/issues/issue-49685.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49854.rs b/src/test/run-pass/issues/issue-49854.rs deleted file mode 100644 index 0e1db00a34c..00000000000 --- a/src/test/run-pass/issues/issue-49854.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49955-2.rs b/src/test/run-pass/issues/issue-49955-2.rs deleted file mode 100644 index 267ed746322..00000000000 --- a/src/test/run-pass/issues/issue-49955-2.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49955.rs b/src/test/run-pass/issues/issue-49955.rs deleted file mode 100644 index f2f3ebff2db..00000000000 --- a/src/test/run-pass/issues/issue-49955.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-49973.rs b/src/test/run-pass/issues/issue-49973.rs deleted file mode 100644 index af421c52fb0..00000000000 --- a/src/test/run-pass/issues/issue-49973.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs b/src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs deleted file mode 100644 index fc869ae4fec..00000000000 --- a/src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/issues/issue-50415.rs b/src/test/run-pass/issues/issue-50415.rs deleted file mode 100644 index 20c7be772f9..00000000000 --- a/src/test/run-pass/issues/issue-50415.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-50442.rs b/src/test/run-pass/issues/issue-50442.rs deleted file mode 100644 index 25c7dde7a5f..00000000000 --- a/src/test/run-pass/issues/issue-50442.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5060.rs b/src/test/run-pass/issues/issue-5060.rs deleted file mode 100644 index c4760bc029b..00000000000 --- a/src/test/run-pass/issues/issue-5060.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-50689.rs b/src/test/run-pass/issues/issue-50689.rs deleted file mode 100644 index b49f2950020..00000000000 --- a/src/test/run-pass/issues/issue-50689.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(unused_variables)] -enum Foo { - Bar = (|x: i32| { }, 42).1, -} - -fn main() { - assert_eq!(Foo::Bar as usize, 42); -} diff --git a/src/test/run-pass/issues/issue-50731.rs b/src/test/run-pass/issues/issue-50731.rs deleted file mode 100644 index 209c1e1279b..00000000000 --- a/src/test/run-pass/issues/issue-50731.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -enum Void {} -fn foo(_: Result<(Void, u32), (Void, String)>) {} -fn main() { - let _: fn(_) = foo; -} diff --git a/src/test/run-pass/issues/issue-50811.rs b/src/test/run-pass/issues/issue-50811.rs deleted file mode 100644 index 63d87e03c48..00000000000 --- a/src/test/run-pass/issues/issue-50811.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs b/src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs deleted file mode 100644 index f3a51b415fa..00000000000 --- a/src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![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/src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs b/src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs deleted file mode 100644 index 16dfac53ad1..00000000000 --- a/src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-51185.rs b/src/test/run-pass/issues/issue-51185.rs deleted file mode 100644 index 52a2b25539d..00000000000 --- a/src/test/run-pass/issues/issue-51185.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -fn foo() -> impl Into fn(&'a ())> { - (|_| {}) as for<'a> fn(&'a ()) -} - -fn main() { - foo().into()(&()); -} diff --git a/src/test/run-pass/issues/issue-51345.rs b/src/test/run-pass/issues/issue-51345.rs deleted file mode 100644 index 15571e8bf5b..00000000000 --- a/src/test/run-pass/issues/issue-51345.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unreachable_code)] - -fn main() { - let mut v = Vec::new(); - - loop { v.push(break) } -} diff --git a/src/test/run-pass/issues/issue-51582.rs b/src/test/run-pass/issues/issue-51582.rs deleted file mode 100644 index 63ef05729bc..00000000000 --- a/src/test/run-pass/issues/issue-51582.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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, unsafe { std::intrinsics::discriminant_value(&make_b()) }); -} diff --git a/src/test/run-pass/issues/issue-51907.rs b/src/test/run-pass/issues/issue-51907.rs deleted file mode 100644 index 3691fe19117..00000000000 --- a/src/test/run-pass/issues/issue-51907.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -trait Foo { - extern fn borrow(&self); - extern fn take(self: Box); -} - -struct Bar; -impl Foo for Bar { - extern fn borrow(&self) {} - extern fn take(self: Box) {} -} - -fn main() { - let foo: Box = Box::new(Bar); - foo.borrow(); - foo.take() -} diff --git a/src/test/run-pass/issues/issue-5192.rs b/src/test/run-pass/issues/issue-5192.rs deleted file mode 100644 index 5a83d1c2ff9..00000000000 --- a/src/test/run-pass/issues/issue-5192.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs b/src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs deleted file mode 100644 index 087005849d1..00000000000 --- a/src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type = "lib"] - -pub fn hello() { - println!("Hello, world!"); -} diff --git a/src/test/run-pass/issues/issue-52140/main.rs b/src/test/run-pass/issues/issue-52140/main.rs deleted file mode 100644 index aeac4340455..00000000000 --- a/src/test/run-pass/issues/issue-52140/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs b/src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs deleted file mode 100644 index 087005849d1..00000000000 --- a/src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_type = "lib"] - -pub fn hello() { - println!("Hello, world!"); -} diff --git a/src/test/run-pass/issues/issue-52141/main.rs b/src/test/run-pass/issues/issue-52141/main.rs deleted file mode 100644 index 7eea1726cf3..00000000000 --- a/src/test/run-pass/issues/issue-52141/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-52169.rs b/src/test/run-pass/issues/issue-52169.rs deleted file mode 100644 index 60be97f0aee..00000000000 --- a/src/test/run-pass/issues/issue-52169.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5239-2.rs b/src/test/run-pass/issues/issue-5239-2.rs deleted file mode 100644 index b501c6e1853..00000000000 --- a/src/test/run-pass/issues/issue-5239-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5243.rs b/src/test/run-pass/issues/issue-5243.rs deleted file mode 100644 index c511d45f02d..00000000000 --- a/src/test/run-pass/issues/issue-5243.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-52557.rs b/src/test/run-pass/issues/issue-52557.rs deleted file mode 100644 index 09f7a8c5131..00000000000 --- a/src/test/run-pass/issues/issue-52557.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-52705/auxiliary/png2.rs b/src/test/run-pass/issues/issue-52705/auxiliary/png2.rs deleted file mode 100644 index fa9956e440d..00000000000 --- a/src/test/run-pass/issues/issue-52705/auxiliary/png2.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type = "lib"] - -pub struct DecodingError; diff --git a/src/test/run-pass/issues/issue-52705/main.rs b/src/test/run-pass/issues/issue-52705/main.rs deleted file mode 100644 index 90bb8ca7537..00000000000 --- a/src/test/run-pass/issues/issue-52705/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5280.rs b/src/test/run-pass/issues/issue-5280.rs deleted file mode 100644 index 3c97dad6b14..00000000000 --- a/src/test/run-pass/issues/issue-5280.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5315.rs b/src/test/run-pass/issues/issue-5315.rs deleted file mode 100644 index 38c98254b93..00000000000 --- a/src/test/run-pass/issues/issue-5315.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -struct A(bool); - -pub fn main() { - let f = A; - f(true); -} diff --git a/src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs b/src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs deleted file mode 100644 index 64aa2836a7d..00000000000 --- a/src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-53333.rs b/src/test/run-pass/issues/issue-53333.rs deleted file mode 100644 index ccc9971f93c..00000000000 --- a/src/test/run-pass/issues/issue-53333.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(unused_imports)] -// edition:2018 - -fn main() { - use std; - let std = "std"; - println!("{}", std); -} diff --git a/src/test/run-pass/issues/issue-53728.rs b/src/test/run-pass/issues/issue-53728.rs deleted file mode 100644 index 77b5010f776..00000000000 --- a/src/test/run-pass/issues/issue-53728.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/issues/issue-53843.rs b/src/test/run-pass/issues/issue-53843.rs deleted file mode 100644 index f305b370ce6..00000000000 --- a/src/test/run-pass/issues/issue-53843.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs b/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs deleted file mode 100644 index 412028bdcdc..00000000000 --- a/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/issues/issue-54467.rs b/src/test/run-pass/issues/issue-54467.rs deleted file mode 100644 index 734bf2768c2..00000000000 --- a/src/test/run-pass/issues/issue-54467.rs +++ /dev/null @@ -1,46 +0,0 @@ -// run-pass - -pub trait Stream { - type Item; - type Error; -} - -pub trait ParseError { - type Output; -} - -impl ParseError for u32 { - type Output = (); -} - -impl Stream for () { - type Item = char; - type Error = u32; -} - -pub struct Lex<'a, I> - where I: Stream, - I::Error: ParseError, - <::Error as ParseError>::Output: 'a -{ - x: &'a >::Output -} - -pub struct Reserved<'a, I> where - I: Stream + 'a, - I::Error: ParseError, - <::Error as ParseError>::Output: 'a - -{ - x: Lex<'a, I> -} - -fn main() { - let r: Reserved<()> = Reserved { - x: Lex { - x: &() - } - }; - - let _v = r.x.x; -} diff --git a/src/test/run-pass/issues/issue-54477-reduced-2.rs b/src/test/run-pass/issues/issue-54477-reduced-2.rs deleted file mode 100644 index 199d69b4540..00000000000 --- a/src/test/run-pass/issues/issue-54477-reduced-2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-54696.rs b/src/test/run-pass/issues/issue-54696.rs deleted file mode 100644 index d8408ed8549..00000000000 --- a/src/test/run-pass/issues/issue-54696.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5518.rs b/src/test/run-pass/issues/issue-5518.rs deleted file mode 100644 index 97ed9ef309d..00000000000 --- a/src/test/run-pass/issues/issue-5518.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-5518.rs - -// pretty-expanded FIXME #23616 - -extern crate issue_5518 as other; - -fn main() {} diff --git a/src/test/run-pass/issues/issue-5521.rs b/src/test/run-pass/issues/issue-5521.rs deleted file mode 100644 index cafdbc39961..00000000000 --- a/src/test/run-pass/issues/issue-5521.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5530.rs b/src/test/run-pass/issues/issue-5530.rs deleted file mode 100644 index 72731cbb177..00000000000 --- a/src/test/run-pass/issues/issue-5530.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/issues/issue-55376.rs b/src/test/run-pass/issues/issue-55376.rs deleted file mode 100644 index 4adff2b4544..00000000000 --- a/src/test/run-pass/issues/issue-55376.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-55380.rs b/src/test/run-pass/issues/issue-55380.rs deleted file mode 100644 index 862218e2192..00000000000 --- a/src/test/run-pass/issues/issue-55380.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass - -#![feature(specialization)] - -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/src/test/run-pass/issues/issue-5550.rs b/src/test/run-pass/issues/issue-5550.rs deleted file mode 100644 index 6ea24747b39..00000000000 --- a/src/test/run-pass/issues/issue-5550.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5554.rs b/src/test/run-pass/issues/issue-5554.rs deleted file mode 100644 index 7737536f43d..00000000000 --- a/src/test/run-pass/issues/issue-5554.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-56237.rs b/src/test/run-pass/issues/issue-56237.rs deleted file mode 100644 index 534b85acec8..00000000000 --- a/src/test/run-pass/issues/issue-56237.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -use std::ops::Deref; - -fn foo

(_value:

::Target) -where - P: Deref, -

::Target: Sized, -{} - -fn main() { - foo::>(2); -} diff --git a/src/test/run-pass/issues/issue-5666.rs b/src/test/run-pass/issues/issue-5666.rs deleted file mode 100644 index aa513277830..00000000000 --- a/src/test/run-pass/issues/issue-5666.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5688.rs b/src/test/run-pass/issues/issue-5688.rs deleted file mode 100644 index b6e364c2f40..00000000000 --- a/src/test/run-pass/issues/issue-5688.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5708.rs b/src/test/run-pass/issues/issue-5708.rs deleted file mode 100644 index 6fe9943d368..00000000000 --- a/src/test/run-pass/issues/issue-5708.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5718.rs b/src/test/run-pass/issues/issue-5718.rs deleted file mode 100644 index 63efec95311..00000000000 --- a/src/test/run-pass/issues/issue-5718.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5741.rs b/src/test/run-pass/issues/issue-5741.rs deleted file mode 100644 index b9eaf0be7fb..00000000000 --- a/src/test/run-pass/issues/issue-5741.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 -#![allow(while_true)] -#![allow(unreachable_code)] - -pub fn main() { - return; - while true {}; -} diff --git a/src/test/run-pass/issues/issue-5791.rs b/src/test/run-pass/issues/issue-5791.rs deleted file mode 100644 index 2f8bf1e9369..00000000000 --- a/src/test/run-pass/issues/issue-5791.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -extern { - #[link_name = "malloc"] - fn malloc1(len: i32) -> *const u8; - #[link_name = "malloc"] - fn malloc2(len: i32, foo: i32) -> *const u8; -} - -pub fn main () {} diff --git a/src/test/run-pass/issues/issue-58212.rs b/src/test/run-pass/issues/issue-58212.rs deleted file mode 100644 index 21dcdd56bf6..00000000000 --- a/src/test/run-pass/issues/issue-58212.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - -trait FromUnchecked { - unsafe fn from_unchecked(); -} - -impl FromUnchecked for [u8; 1] { - unsafe fn from_unchecked() { - #[allow(deprecated)] - let mut array: Self = std::mem::uninitialized(); - let _ptr = &mut array as *mut [u8] as *mut u8; - } -} - -fn main() { -} diff --git a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs b/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs deleted file mode 100644 index fac727d2d7d..00000000000 --- a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-58463.rs b/src/test/run-pass/issues/issue-58463.rs deleted file mode 100644 index 8ab845366b7..00000000000 --- a/src/test/run-pass/issues/issue-58463.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// compile-flags:-C debuginfo=2 -fn foo() -> impl Copy { - foo -} -fn main() { - foo(); -} diff --git a/src/test/run-pass/issues/issue-5917.rs b/src/test/run-pass/issues/issue-5917.rs deleted file mode 100644 index 6ab7081cf88..00000000000 --- a/src/test/run-pass/issues/issue-5917.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5988.rs b/src/test/run-pass/issues/issue-5988.rs deleted file mode 100644 index 303fb4fbc94..00000000000 --- a/src/test/run-pass/issues/issue-5988.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-5997.rs b/src/test/run-pass/issues/issue-5997.rs deleted file mode 100644 index 145e3a7928d..00000000000 --- a/src/test/run-pass/issues/issue-5997.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6117.rs b/src/test/run-pass/issues/issue-6117.rs deleted file mode 100644 index 5235d53d84a..00000000000 --- a/src/test/run-pass/issues/issue-6117.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6128.rs b/src/test/run-pass/issues/issue-6128.rs deleted file mode 100644 index 8859fbe6afb..00000000000 --- a/src/test/run-pass/issues/issue-6128.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6130.rs b/src/test/run-pass/issues/issue-6130.rs deleted file mode 100644 index a33ea686947..00000000000 --- a/src/test/run-pass/issues/issue-6130.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6153.rs b/src/test/run-pass/issues/issue-6153.rs deleted file mode 100644 index 25f026f214b..00000000000 --- a/src/test/run-pass/issues/issue-6153.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6157.rs b/src/test/run-pass/issues/issue-6157.rs deleted file mode 100644 index b7a44ed8623..00000000000 --- a/src/test/run-pass/issues/issue-6157.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/issues/issue-61696.rs b/src/test/run-pass/issues/issue-61696.rs deleted file mode 100644 index dca52927fd7..00000000000 --- a/src/test/run-pass/issues/issue-61696.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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/src/test/run-pass/issues/issue-61894.rs b/src/test/run-pass/issues/issue-61894.rs deleted file mode 100644 index c018ac73fb5..00000000000 --- a/src/test/run-pass/issues/issue-61894.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6318.rs b/src/test/run-pass/issues/issue-6318.rs deleted file mode 100644 index d8bd83f0dc6..00000000000 --- a/src/test/run-pass/issues/issue-6318.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6334.rs b/src/test/run-pass/issues/issue-6334.rs deleted file mode 100644 index acf48da1543..00000000000 --- a/src/test/run-pass/issues/issue-6334.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6344-let.rs b/src/test/run-pass/issues/issue-6344-let.rs deleted file mode 100644 index a7b6a2e2d66..00000000000 --- a/src/test/run-pass/issues/issue-6344-let.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6344-match.rs b/src/test/run-pass/issues/issue-6344-match.rs deleted file mode 100644 index 4505a34c716..00000000000 --- a/src/test/run-pass/issues/issue-6344-match.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6449.rs b/src/test/run-pass/issues/issue-6449.rs deleted file mode 100644 index bfd4c123208..00000000000 --- a/src/test/run-pass/issues/issue-6449.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6892.rs b/src/test/run-pass/issues/issue-6892.rs deleted file mode 100644 index a361461a4ce..00000000000 --- a/src/test/run-pass/issues/issue-6892.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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/src/test/run-pass/issues/issue-6919.rs b/src/test/run-pass/issues/issue-6919.rs deleted file mode 100644 index 11aed120873..00000000000 --- a/src/test/run-pass/issues/issue-6919.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(unused_attributes)] -// aux-build:iss.rs - -// pretty-expanded FIXME #23616 - -#![crate_id="issue-6919"] -extern crate issue6919_3; - -pub fn main() { - let _ = issue6919_3::D.k; -} diff --git a/src/test/run-pass/issues/issue-7012.rs b/src/test/run-pass/issues/issue-7012.rs deleted file mode 100644 index 90eba170695..00000000000 --- a/src/test/run-pass/issues/issue-7012.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7178.rs b/src/test/run-pass/issues/issue-7178.rs deleted file mode 100644 index 30aa736cdc6..00000000000 --- a/src/test/run-pass/issues/issue-7178.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7222.rs b/src/test/run-pass/issues/issue-7222.rs deleted file mode 100644 index 64907316626..00000000000 --- a/src/test/run-pass/issues/issue-7222.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7344.rs b/src/test/run-pass/issues/issue-7344.rs deleted file mode 100644 index f1727d0c1ae..00000000000 --- a/src/test/run-pass/issues/issue-7344.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs b/src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs deleted file mode 100644 index 7d838cbb09b..00000000000 --- a/src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -/* -#7519 ICE pattern matching unit in function argument -*/ - -fn foo(():()) { } - -pub fn main() { - foo(()); -} diff --git a/src/test/run-pass/issues/issue-7563.rs b/src/test/run-pass/issues/issue-7563.rs deleted file mode 100644 index c62405554b4..00000000000 --- a/src/test/run-pass/issues/issue-7563.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7575.rs b/src/test/run-pass/issues/issue-7575.rs deleted file mode 100644 index ac69f2b1c80..00000000000 --- a/src/test/run-pass/issues/issue-7575.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7660.rs b/src/test/run-pass/issues/issue-7660.rs deleted file mode 100644 index ad0b8ecff39..00000000000 --- a/src/test/run-pass/issues/issue-7660.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7663.rs b/src/test/run-pass/issues/issue-7663.rs deleted file mode 100644 index b15e215db0f..00000000000 --- a/src/test/run-pass/issues/issue-7663.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7784.rs b/src/test/run-pass/issues/issue-7784.rs deleted file mode 100644 index b75e547079e..00000000000 --- a/src/test/run-pass/issues/issue-7784.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/issues/issue-7899.rs b/src/test/run-pass/issues/issue-7899.rs deleted file mode 100644 index fb631f83697..00000000000 --- a/src/test/run-pass/issues/issue-7899.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-7911.rs b/src/test/run-pass/issues/issue-7911.rs deleted file mode 100644 index de833324bd2..00000000000 --- a/src/test/run-pass/issues/issue-7911.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8044.rs b/src/test/run-pass/issues/issue-8044.rs deleted file mode 100644 index 858f98b654d..00000000000 --- a/src/test/run-pass/issues/issue-8044.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8248.rs b/src/test/run-pass/issues/issue-8248.rs deleted file mode 100644 index 31a305c31be..00000000000 --- a/src/test/run-pass/issues/issue-8248.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8249.rs b/src/test/run-pass/issues/issue-8249.rs deleted file mode 100644 index d09dff3a697..00000000000 --- a/src/test/run-pass/issues/issue-8249.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8259.rs b/src/test/run-pass/issues/issue-8259.rs deleted file mode 100644 index 2802bea7fe0..00000000000 --- a/src/test/run-pass/issues/issue-8259.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8351-1.rs b/src/test/run-pass/issues/issue-8351-1.rs deleted file mode 100644 index 139f027cb90..00000000000 --- a/src/test/run-pass/issues/issue-8351-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8351-2.rs b/src/test/run-pass/issues/issue-8351-2.rs deleted file mode 100644 index bc66cbb77c0..00000000000 --- a/src/test/run-pass/issues/issue-8351-2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8391.rs b/src/test/run-pass/issues/issue-8391.rs deleted file mode 100644 index 1a90369659b..00000000000 --- a/src/test/run-pass/issues/issue-8391.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -fn main() { - let x = match Some(1) { - ref _y @ Some(_) => 1, - None => 2, - }; - assert_eq!(x, 1); -} diff --git a/src/test/run-pass/issues/issue-8401.rs b/src/test/run-pass/issues/issue-8401.rs deleted file mode 100644 index 1257bab6c0c..00000000000 --- a/src/test/run-pass/issues/issue-8401.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-8401.rs - -// pretty-expanded FIXME #23616 - -extern crate issue_8401; - -pub fn main() {} diff --git a/src/test/run-pass/issues/issue-8460.rs b/src/test/run-pass/issues/issue-8460.rs deleted file mode 100644 index b7fc564a9b5..00000000000 --- a/src/test/run-pass/issues/issue-8460.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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() -> $t { 0 } - fn one() -> $t { 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_value() / -isize::one(), - i8::min_value() / -i8::one(), - i16::min_value() / -i16::one(), - i32::min_value() / -i32::one(), - i64::min_value() / -i64::one(), - 1isize / isize::zero(), - 1i8 / i8::zero(), - 1i16 / i16::zero(), - 1i32 / i32::zero(), - 1i64 / i64::zero(), - isize::min_value() % -isize::one(), - i8::min_value() % -i8::one(), - i16::min_value() % -i16::one(), - i32::min_value() % -i32::one(), - i64::min_value() % -i64::one(), - 1isize % isize::zero(), - 1i8 % i8::zero(), - 1i16 % i16::zero(), - 1i32 % i32::zero(), - 1i64 % i64::zero() - ]; -} diff --git a/src/test/run-pass/issues/issue-8498.rs b/src/test/run-pass/issues/issue-8498.rs deleted file mode 100644 index e6241b76109..00000000000 --- a/src/test/run-pass/issues/issue-8498.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8506.rs b/src/test/run-pass/issues/issue-8506.rs deleted file mode 100644 index cc32b89234f..00000000000 --- a/src/test/run-pass/issues/issue-8506.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-868.rs b/src/test/run-pass/issues/issue-868.rs deleted file mode 100644 index ce0a3c7ca52..00000000000 --- a/src/test/run-pass/issues/issue-868.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8709.rs b/src/test/run-pass/issues/issue-8709.rs deleted file mode 100644 index ea7525d4477..00000000000 --- a/src/test/run-pass/issues/issue-8709.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8783.rs b/src/test/run-pass/issues/issue-8783.rs deleted file mode 100644 index 4eb49c82161..00000000000 --- a/src/test/run-pass/issues/issue-8783.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8827.rs b/src/test/run-pass/issues/issue-8827.rs deleted file mode 100644 index 95be7616a4f..00000000000 --- a/src/test/run-pass/issues/issue-8827.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8851.rs b/src/test/run-pass/issues/issue-8851.rs deleted file mode 100644 index faacfe5f895..00000000000 --- a/src/test/run-pass/issues/issue-8851.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8860.rs b/src/test/run-pass/issues/issue-8860.rs deleted file mode 100644 index b89a80c1307..00000000000 --- a/src/test/run-pass/issues/issue-8860.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/issues/issue-8898.rs b/src/test/run-pass/issues/issue-8898.rs deleted file mode 100644 index 31d5ff86e7c..00000000000 --- a/src/test/run-pass/issues/issue-8898.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9047.rs b/src/test/run-pass/issues/issue-9047.rs deleted file mode 100644 index fa8d75aec7a..00000000000 --- a/src/test/run-pass/issues/issue-9047.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9123.rs b/src/test/run-pass/issues/issue-9123.rs deleted file mode 100644 index 8c21d06c477..00000000000 --- a/src/test/run-pass/issues/issue-9123.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// aux-build:issue-9123.rs - -// pretty-expanded FIXME #23616 - -extern crate issue_9123; - -pub fn main() {} diff --git a/src/test/run-pass/issues/issue-9129.rs b/src/test/run-pass/issues/issue-9129.rs deleted file mode 100644 index 3d87e1c2037..00000000000 --- a/src/test/run-pass/issues/issue-9129.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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 { 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/src/test/run-pass/issues/issue-9155.rs b/src/test/run-pass/issues/issue-9155.rs deleted file mode 100644 index 4b5c451e853..00000000000 --- a/src/test/run-pass/issues/issue-9155.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9188.rs b/src/test/run-pass/issues/issue-9188.rs deleted file mode 100644 index 34e61fdf68b..00000000000 --- a/src/test/run-pass/issues/issue-9188.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9259.rs b/src/test/run-pass/issues/issue-9259.rs deleted file mode 100644 index d838edbdd66..00000000000 --- a/src/test/run-pass/issues/issue-9259.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9382.rs b/src/test/run-pass/issues/issue-9382.rs deleted file mode 100644 index dbb0fa524ef..00000000000 --- a/src/test/run-pass/issues/issue-9382.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs b/src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs deleted file mode 100644 index cc0dd4fc14a..00000000000 --- a/src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs +++ /dev/null @@ -1,62 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9396.rs b/src/test/run-pass/issues/issue-9396.rs deleted file mode 100644 index 27b5185377d..00000000000 --- a/src/test/run-pass/issues/issue-9396.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -#![allow(unused_must_use)] -#![allow(deprecated)] -// ignore-emscripten no threads support -// ignore-sgx no thread sleep 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/src/test/run-pass/issues/issue-9446.rs b/src/test/run-pass/issues/issue-9446.rs deleted file mode 100644 index e200840d290..00000000000 --- a/src/test/run-pass/issues/issue-9446.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9737.rs b/src/test/run-pass/issues/issue-9737.rs deleted file mode 100644 index 7d3e0567847..00000000000 --- a/src/test/run-pass/issues/issue-9737.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(unused_variables)] -macro_rules! f { - (v: $x:expr) => ( println!("{}", $x) ) -} - -fn main () { - let v = 5; - f!(v: 3); -} diff --git a/src/test/run-pass/issues/issue-979.rs b/src/test/run-pass/issues/issue-979.rs deleted file mode 100644 index 57a99b325ad..00000000000 --- a/src/test/run-pass/issues/issue-979.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9837.rs b/src/test/run-pass/issues/issue-9837.rs deleted file mode 100644 index 5d2c822a576..00000000000 --- a/src/test/run-pass/issues/issue-9837.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9906.rs b/src/test/run-pass/issues/issue-9906.rs deleted file mode 100644 index a2870cf0f6e..00000000000 --- a/src/test/run-pass/issues/issue-9906.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9918.rs b/src/test/run-pass/issues/issue-9918.rs deleted file mode 100644 index 63ad7040d67..00000000000 --- a/src/test/run-pass/issues/issue-9918.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -pub fn main() { - assert_eq!((0 + 0u8) as char, '\0'); -} diff --git a/src/test/run-pass/issues/issue-9942.rs b/src/test/run-pass/issues/issue-9942.rs deleted file mode 100644 index f4880446526..00000000000 --- a/src/test/run-pass/issues/issue-9942.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - const S: usize = 23 as usize; [0; S]; () -} diff --git a/src/test/run-pass/issues/issue-9951.rs b/src/test/run-pass/issues/issue-9951.rs deleted file mode 100644 index 2698a3b17c6..00000000000 --- a/src/test/run-pass/issues/issue-9951.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/issues/issue-9968.rs b/src/test/run-pass/issues/issue-9968.rs deleted file mode 100644 index 3ab90d99af9..00000000000 --- a/src/test/run-pass/issues/issue-9968.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/istr.rs b/src/test/run-pass/istr.rs deleted file mode 100644 index dca6d40d59a..00000000000 --- a/src/test/run-pass/istr.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/item-name-overload.rs b/src/test/run-pass/item-name-overload.rs deleted file mode 100644 index c8a302a2c5b..00000000000 --- a/src/test/run-pass/item-name-overload.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/iterators/into-iterator-type-inference-shift.rs b/src/test/run-pass/iterators/into-iterator-type-inference-shift.rs deleted file mode 100644 index 9151172fd15..00000000000 --- a/src/test/run-pass/iterators/into-iterator-type-inference-shift.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/iterators/iter-cloned-type-inference.rs b/src/test/run-pass/iterators/iter-cloned-type-inference.rs deleted file mode 100644 index 898e3371971..00000000000 --- a/src/test/run-pass/iterators/iter-cloned-type-inference.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/iterators/iter-range.rs b/src/test/run-pass/iterators/iter-range.rs deleted file mode 100644 index 993d93790e0..00000000000 --- a/src/test/run-pass/iterators/iter-range.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/iterators/iter-step-overflow-debug.rs b/src/test/run-pass/iterators/iter-step-overflow-debug.rs deleted file mode 100644 index 5d67c7cbb42..00000000000 --- a/src/test/run-pass/iterators/iter-step-overflow-debug.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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_value()..; - it.next().unwrap(); // 255 - it.next().unwrap(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - let mut it = i8::max_value()..; - it.next().unwrap(); // 127 - it.next().unwrap(); - }); - assert!(r.is_err()); -} diff --git a/src/test/run-pass/iterators/iter-step-overflow-ndebug.rs b/src/test/run-pass/iterators/iter-step-overflow-ndebug.rs deleted file mode 100644 index a0ad92071b6..00000000000 --- a/src/test/run-pass/iterators/iter-step-overflow-ndebug.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// compile-flags: -C debug_assertions=no - -fn main() { - let mut it = u8::max_value()..; - assert_eq!(it.next().unwrap(), 255); - assert_eq!(it.next().unwrap(), u8::min_value()); - - let mut it = i8::max_value()..; - assert_eq!(it.next().unwrap(), 127); - assert_eq!(it.next().unwrap(), i8::min_value()); -} diff --git a/src/test/run-pass/iterators/iter-sum-overflow-debug.rs b/src/test/run-pass/iterators/iter-sum-overflow-debug.rs deleted file mode 100644 index ee4ab4d24c6..00000000000 --- a/src/test/run-pass/iterators/iter-sum-overflow-debug.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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_value()].iter().sum::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().product::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().cloned().sum::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().cloned().product::(); - }); - assert!(r.is_err()); -} diff --git a/src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs b/src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs deleted file mode 100644 index 61d63d41fb8..00000000000 --- a/src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -// compile-flags: -C debug_assertions=no - -fn main() { - assert_eq!([1i32, i32::max_value()].iter().sum::(), - 1i32.wrapping_add(i32::max_value())); - assert_eq!([2i32, i32::max_value()].iter().product::(), - 2i32.wrapping_mul(i32::max_value())); - - assert_eq!([1i32, i32::max_value()].iter().cloned().sum::(), - 1i32.wrapping_add(i32::max_value())); - assert_eq!([2i32, i32::max_value()].iter().cloned().product::(), - 2i32.wrapping_mul(i32::max_value())); -} diff --git a/src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs deleted file mode 100644 index 429f8e0bc96..00000000000 --- a/src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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_value()].iter().sum::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().product::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().cloned().sum::(); - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().cloned().product::(); - }); - assert!(r.is_err()); -} diff --git a/src/test/run-pass/iterators/iter-zip.rs b/src/test/run-pass/iterators/iter-zip.rs deleted file mode 100644 index a76fa2408bb..00000000000 --- a/src/test/run-pass/iterators/iter-zip.rs +++ /dev/null @@ -1,103 +0,0 @@ -// run-pass -// Test that .zip() specialization preserves side effects -// in sideeffectful iterator adaptors. - -use std::cell::Cell; - -#[derive(Debug)] -struct CountClone(Cell); - -fn count_clone() -> CountClone { CountClone(Cell::new(0)) } - -impl PartialEq for CountClone { - fn eq(&self, rhs: &i32) -> bool { - self.0.get() == *rhs - } -} - -impl Clone for CountClone { - fn clone(&self) -> Self { - let ret = CountClone(self.0.clone()); - let n = self.0.get(); - self.0.set(n + 1); - ret - } -} - -fn test_zip_cloned_sideffectful() { - let xs = [count_clone(), count_clone(), count_clone(), count_clone()]; - let ys = [count_clone(), count_clone()]; - - for _ in xs.iter().cloned().zip(ys.iter().cloned()) { } - - assert_eq!(&xs, &[1, 1, 1, 0][..]); - assert_eq!(&ys, &[1, 1][..]); - - let xs = [count_clone(), count_clone()]; - let ys = [count_clone(), count_clone(), count_clone(), count_clone()]; - - for _ in xs.iter().cloned().zip(ys.iter().cloned()) { } - - assert_eq!(&xs, &[1, 1][..]); - assert_eq!(&ys, &[1, 1, 0, 0][..]); -} - -fn test_zip_map_sideffectful() { - let mut xs = [0; 6]; - let mut ys = [0; 4]; - - for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) { } - - assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]); - assert_eq!(&ys, &[1, 1, 1, 1]); - - let mut xs = [0; 4]; - let mut ys = [0; 6]; - - for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) { } - - assert_eq!(&xs, &[1, 1, 1, 1]); - assert_eq!(&ys, &[1, 1, 1, 1, 0, 0]); -} - -fn test_zip_map_rev_sideffectful() { - let mut xs = [0; 6]; - let mut ys = [0; 4]; - - { - let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)); - it.next_back(); - } - assert_eq!(&xs, &[0, 0, 0, 1, 1, 1]); - assert_eq!(&ys, &[0, 0, 0, 1]); - - let mut xs = [0; 6]; - let mut ys = [0; 4]; - - { - let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)); - (&mut it).take(5).count(); - it.next_back(); - } - assert_eq!(&xs, &[1, 1, 1, 1, 1, 1]); - assert_eq!(&ys, &[1, 1, 1, 1]); -} - -fn test_zip_nested_sideffectful() { - let mut xs = [0; 6]; - let ys = [0; 4]; - - { - // test that it has the side effect nested inside enumerate - let it = xs.iter_mut().map(|x| *x = 1).enumerate().zip(&ys); - it.count(); - } - assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]); -} - -fn main() { - test_zip_cloned_sideffectful(); - test_zip_map_sideffectful(); - test_zip_map_rev_sideffectful(); - test_zip_nested_sideffectful(); -} diff --git a/src/test/run-pass/keyword-changes-2012-07-31.rs b/src/test/run-pass/keyword-changes-2012-07-31.rs deleted file mode 100644 index 1b38527ec29..00000000000 --- a/src/test/run-pass/keyword-changes-2012-07-31.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs deleted file mode 100644 index 5b5d86eec2c..00000000000 --- a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/kinds-in-metadata.rs b/src/test/run-pass/kinds-in-metadata.rs deleted file mode 100644 index 136037a7acf..00000000000 --- a/src/test/run-pass/kinds-in-metadata.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/lambda-infer-unresolved.rs b/src/test/run-pass/lambda-infer-unresolved.rs deleted file mode 100644 index 9cc466b28ec..00000000000 --- a/src/test/run-pass/lambda-infer-unresolved.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/lambda-var-hygiene.rs b/src/test/run-pass/lambda-var-hygiene.rs deleted file mode 100644 index bf06765e5dd..00000000000 --- a/src/test/run-pass/lambda-var-hygiene.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/large-records.rs b/src/test/run-pass/large-records.rs deleted file mode 100644 index 7f850a94e89..00000000000 --- a/src/test/run-pass/large-records.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/last-use-in-block.rs b/src/test/run-pass/last-use-in-block.rs deleted file mode 100644 index 1ab847dcd8a..00000000000 --- a/src/test/run-pass/last-use-in-block.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/run-pass/last-use-in-cap-clause.rs deleted file mode 100644 index 98d43463287..00000000000 --- a/src/test/run-pass/last-use-in-cap-clause.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/last-use-is-capture.rs b/src/test/run-pass/last-use-is-capture.rs deleted file mode 100644 index af230877793..00000000000 --- a/src/test/run-pass/last-use-is-capture.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/lazy-and-or.rs b/src/test/run-pass/lazy-and-or.rs deleted file mode 100644 index 0b44a70a569..00000000000 --- a/src/test/run-pass/lazy-and-or.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/lazy-init.rs b/src/test/run-pass/lazy-init.rs deleted file mode 100644 index a4b5d18bb33..00000000000 --- a/src/test/run-pass/lazy-init.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/leak-unique-as-tydesc.rs b/src/test/run-pass/leak-unique-as-tydesc.rs deleted file mode 100644 index 752081b78f2..00000000000 --- a/src/test/run-pass/leak-unique-as-tydesc.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/lex-bare-cr-nondoc-comment.rs b/src/test/run-pass/lex-bare-cr-nondoc-comment.rs deleted file mode 100644 index 5b528d6e1e1..00000000000 --- a/src/test/run-pass/lex-bare-cr-nondoc-comment.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs b/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs deleted file mode 100644 index 2ca88c2b995..00000000000 --- a/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs +++ /dev/null @@ -1,41 +0,0 @@ -// run-pass -// ignore-tidy-cr ignore-license -// ignore-tidy-cr (repeated again because of tidy bug) -// license is ignored because tidy can't handle the CRLF here properly. - -// http://rust-lang.org/COPYRIGHT. -// - -// 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/src/test/run-pass/lexical-scoping.rs b/src/test/run-pass/lexical-scoping.rs deleted file mode 100644 index 04904958a6c..00000000000 --- a/src/test/run-pass/lexical-scoping.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/lib-defaults.rs b/src/test/run-pass/lib-defaults.rs deleted file mode 100644 index cd0b0bb2321..00000000000 --- a/src/test/run-pass/lib-defaults.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/link-cfg-works.rs b/src/test/run-pass/link-cfg-works.rs deleted file mode 100644 index fe1b569dff6..00000000000 --- a/src/test/run-pass/link-cfg-works.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/link-section.rs b/src/test/run-pass/link-section.rs deleted file mode 100644 index 6958eeda697..00000000000 --- a/src/test/run-pass/link-section.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/linkage1.rs b/src/test/run-pass/linkage1.rs deleted file mode 100644 index bda4da53dbc..00000000000 --- a/src/test/run-pass/linkage1.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/lint-cap.rs b/src/test/run-pass/lint-cap.rs deleted file mode 100644 index 461b923ccd4..00000000000 --- a/src/test/run-pass/lint-cap.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// compile-flags: --cap-lints allow - -#![deny(warnings)] - -use std::option; - -fn main() {} diff --git a/src/test/run-pass/lint-dead-code-associated-type.rs b/src/test/run-pass/lint-dead-code-associated-type.rs deleted file mode 100644 index 1cf66e75a95..00000000000 --- a/src/test/run-pass/lint-dead-code-associated-type.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/lint-dead-code-variant.rs b/src/test/run-pass/lint-dead-code-variant.rs deleted file mode 100644 index 91c97232eed..00000000000 --- a/src/test/run-pass/lint-dead-code-variant.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -#![deny(dead_code)] - -enum Foo { - A, - B, -} - -pub fn main() { - match Foo::A { - Foo::A | Foo::B => Foo::B - }; -} diff --git a/src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs b/src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs deleted file mode 100644 index 07a32904a5e..00000000000 --- a/src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/lint-unknown-lints-at-crate-level.rs b/src/test/run-pass/lint-unknown-lints-at-crate-level.rs deleted file mode 100644 index 61d27f1eff1..00000000000 --- a/src/test/run-pass/lint-unknown-lints-at-crate-level.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// compile-flags: -D warnings -D unknown-lints - -#![allow(unknown_lints)] -#![allow(random_lint_name)] - -fn main() {} diff --git a/src/test/run-pass/list.rs b/src/test/run-pass/list.rs deleted file mode 100644 index 2ac5733b419..00000000000 --- a/src/test/run-pass/list.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/liveness-assign-imm-local-after-ret.rs b/src/test/run-pass/liveness-assign-imm-local-after-ret.rs deleted file mode 100644 index b463f4368d1..00000000000 --- a/src/test/run-pass/liveness-assign-imm-local-after-ret.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/llvm-pr32379.rs b/src/test/run-pass/llvm-pr32379.rs deleted file mode 100644 index 8a1f03241b1..00000000000 --- a/src/test/run-pass/llvm-pr32379.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/log-err-phi.rs b/src/test/run-pass/log-err-phi.rs deleted file mode 100644 index c0e04d2c973..00000000000 --- a/src/test/run-pass/log-err-phi.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - if false { - println!("{}", "foobar"); - } -} diff --git a/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs b/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs deleted file mode 100644 index c5a40edbeef..00000000000 --- a/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/log-knows-the-names-of-variants.rs b/src/test/run-pass/log-knows-the-names-of-variants.rs deleted file mode 100644 index cf2876b6eee..00000000000 --- a/src/test/run-pass/log-knows-the-names-of-variants.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/log-poly.rs b/src/test/run-pass/log-poly.rs deleted file mode 100644 index 14e1b40e168..00000000000 --- a/src/test/run-pass/log-poly.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -#[derive(Debug)] -enum Numbers { - Three -} - -pub fn main() { - println!("{:?}", 1); - println!("{:?}", 2.0f64); - println!("{:?}", Numbers::Three); - println!("{:?}", vec![4]); -} diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs deleted file mode 100644 index 6b49c441d1e..00000000000 --- a/src/test/run-pass/logging-only-prints-once.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// ignore-windows -// ignore-emscripten no threads support -// exec-env:RUSTC_LOG=debug - -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/src/test/run-pass/logging_before_rt_started.rs b/src/test/run-pass/logging_before_rt_started.rs deleted file mode 100644 index 540d2b4f58a..00000000000 --- a/src/test/run-pass/logging_before_rt_started.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// exec-env:RUSTC_LOG=std::ptr - -// In issue #9487, it was realized that std::ptr was invoking the logging -// infrastructure, and when std::ptr was used during runtime initialization, -// this caused some serious problems. The problems have since been fixed, but -// this test will trigger "output during runtime initialization" to make sure -// that the bug isn't re-introduced. - -// pretty-expanded FIXME #23616 - -pub fn main() {} diff --git a/src/test/run-pass/long-while.rs b/src/test/run-pass/long-while.rs deleted file mode 100644 index 529cca7b731..00000000000 --- a/src/test/run-pass/long-while.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/lto-many-codegen-units.rs b/src/test/run-pass/lto-many-codegen-units.rs deleted file mode 100644 index f0f461ffec8..00000000000 --- a/src/test/run-pass/lto-many-codegen-units.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// compile-flags: -C lto -C codegen-units=8 -// no-prefer-dynamic - -fn main() { -} diff --git a/src/test/run-pass/lto-still-runs-thread-dtors.rs b/src/test/run-pass/lto-still-runs-thread-dtors.rs deleted file mode 100644 index 635ad783b31..00000000000 --- a/src/test/run-pass/lto-still-runs-thread-dtors.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/lub-glb-with-unbound-infer-var.rs b/src/test/run-pass/lub-glb-with-unbound-infer-var.rs deleted file mode 100644 index c9e117089f5..00000000000 --- a/src/test/run-pass/lub-glb-with-unbound-infer-var.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/macro-quote-cond.rs b/src/test/run-pass/macro-quote-cond.rs deleted file mode 100644 index 569451e4259..00000000000 --- a/src/test/run-pass/macro-quote-cond.rs +++ /dev/null @@ -1,48 +0,0 @@ -// run-pass - -#![allow(unused_parens)] -// aux-build:cond_plugin.rs - -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/macro-quote-test.rs b/src/test/run-pass/macro-quote-test.rs deleted file mode 100644 index 7815b8e6df1..00000000000 --- a/src/test/run-pass/macro-quote-test.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// Test that a macro can emit delimiters with nothing inside - `()`, `{}` - -// aux-build:hello_macro.rs - -#![feature(proc_macro_hygiene)] - -extern crate hello_macro; - -fn main() { - hello_macro::hello!(); -} diff --git a/src/test/run-pass/macros/assert-eq-macro-success.rs b/src/test/run-pass/macros/assert-eq-macro-success.rs deleted file mode 100644 index 57858b34837..00000000000 --- a/src/test/run-pass/macros/assert-eq-macro-success.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/macros/assert-eq-macro-unsized.rs b/src/test/run-pass/macros/assert-eq-macro-unsized.rs deleted file mode 100644 index 00823216bf6..00000000000 --- a/src/test/run-pass/macros/assert-eq-macro-unsized.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -pub fn main() { - assert_eq!([1, 2, 3][..], vec![1, 2, 3][..]); -} diff --git a/src/test/run-pass/macros/assert-ne-macro-success.rs b/src/test/run-pass/macros/assert-ne-macro-success.rs deleted file mode 100644 index 89b3a4c9d6a..00000000000 --- a/src/test/run-pass/macros/assert-ne-macro-success.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/macros/assert-ne-macro-unsized.rs b/src/test/run-pass/macros/assert-ne-macro-unsized.rs deleted file mode 100644 index e8a86e3da06..00000000000 --- a/src/test/run-pass/macros/assert-ne-macro-unsized.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -pub fn main() { - assert_ne!([6, 6, 6][..], vec![1, 2, 3][..]); -} diff --git a/src/test/run-pass/macros/auxiliary/macro-comma-support.rs b/src/test/run-pass/macros/auxiliary/macro-comma-support.rs deleted file mode 100644 index 6a452c185a8..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro-comma-support.rs +++ /dev/null @@ -1 +0,0 @@ -() diff --git a/src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs b/src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs deleted file mode 100644 index 7394f194b80..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs +++ /dev/null @@ -1,3 +0,0 @@ -// ignore-test: this is not a test - -1 diff --git a/src/test/run-pass/macros/auxiliary/macro-include-items-item.rs b/src/test/run-pass/macros/auxiliary/macro-include-items-item.rs deleted file mode 100644 index 7d54745e03b..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro-include-items-item.rs +++ /dev/null @@ -1,3 +0,0 @@ -// ignore-test: this is not a test - -fn foo() { bar() } diff --git a/src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs b/src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs deleted file mode 100644 index c267eefde02..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[macro_export] -macro_rules! make_a_5 { - () => (5) -} diff --git a/src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs b/src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs deleted file mode 100644 index d71af9ee6f2..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod inner { - #[macro_export] - macro_rules! foo { - () => (1) - } -} diff --git a/src/test/run-pass/macros/auxiliary/macro_with_super_1.rs b/src/test/run-pass/macros/auxiliary/macro_with_super_1.rs deleted file mode 100644 index b015500df06..00000000000 --- a/src/test/run-pass/macros/auxiliary/macro_with_super_1.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![crate_type = "lib"] - -#[macro_export] -macro_rules! declare { - () => ( - pub fn aaa() {} - - pub mod bbb { - use super::aaa; - - pub fn ccc() { - aaa(); - } - } - ) -} diff --git a/src/test/run-pass/macros/auxiliary/two_macros.rs b/src/test/run-pass/macros/auxiliary/two_macros.rs deleted file mode 100644 index 441a978dd69..00000000000 --- a/src/test/run-pass/macros/auxiliary/two_macros.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[macro_export] -macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } - -#[macro_export] -macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } diff --git a/src/test/run-pass/macros/auxiliary/use-macro-self.rs b/src/test/run-pass/macros/auxiliary/use-macro-self.rs deleted file mode 100644 index f1307411a7f..00000000000 --- a/src/test/run-pass/macros/auxiliary/use-macro-self.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod foobarius {} - -#[macro_export] -macro_rules! foobarius { - () => { () } -} diff --git a/src/test/run-pass/macros/colorful-write-macros.rs b/src/test/run-pass/macros/colorful-write-macros.rs deleted file mode 100644 index eb1872cc7f0..00000000000 --- a/src/test/run-pass/macros/colorful-write-macros.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/macros/conditional-debug-macro-on.rs b/src/test/run-pass/macros/conditional-debug-macro-on.rs deleted file mode 100644 index 8665da89758..00000000000 --- a/src/test/run-pass/macros/conditional-debug-macro-on.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/macros/die-macro.rs b/src/test/run-pass/macros/die-macro.rs deleted file mode 100644 index 2a726efe822..00000000000 --- a/src/test/run-pass/macros/die-macro.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/macros/issue-25274.rs b/src/test/run-pass/macros/issue-25274.rs deleted file mode 100644 index 65b29bba8c8..00000000000 --- a/src/test/run-pass/macros/issue-25274.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs b/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs deleted file mode 100644 index 2d78ae6f908..00000000000 --- a/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout b/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout deleted file mode 100644 index b28b04f6431..00000000000 --- a/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/test/run-pass/macros/macro-2.rs b/src/test/run-pass/macros/macro-2.rs deleted file mode 100644 index 4890c991dcd..00000000000 --- a/src/test/run-pass/macros/macro-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/macros/macro-as-fn-body.rs b/src/test/run-pass/macros/macro-as-fn-body.rs deleted file mode 100644 index 6781c9a9ed4..00000000000 --- a/src/test/run-pass/macros/macro-as-fn-body.rs +++ /dev/null @@ -1,33 +0,0 @@ -// -// 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/src/test/run-pass/macros/macro-attribute-expansion.rs b/src/test/run-pass/macros/macro-attribute-expansion.rs deleted file mode 100644 index f01e5c44a67..00000000000 --- a/src/test/run-pass/macros/macro-attribute-expansion.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/macros/macro-attributes.rs b/src/test/run-pass/macros/macro-attributes.rs deleted file mode 100644 index d382e8b7197..00000000000 --- a/src/test/run-pass/macros/macro-attributes.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/macros/macro-block-nonterminal.rs b/src/test/run-pass/macros/macro-block-nonterminal.rs deleted file mode 100644 index a6c9dd6e187..00000000000 --- a/src/test/run-pass/macros/macro-block-nonterminal.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/macros/macro-crate-def-only.rs b/src/test/run-pass/macros/macro-crate-def-only.rs deleted file mode 100644 index 514b33e3897..00000000000 --- a/src/test/run-pass/macros/macro-crate-def-only.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs b/src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs deleted file mode 100644 index 87bd397f065..00000000000 --- a/src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/macros/macro-crate-nonterminal.rs b/src/test/run-pass/macros/macro-crate-nonterminal.rs deleted file mode 100644 index 4b1056fc725..00000000000 --- a/src/test/run-pass/macros/macro-crate-nonterminal.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/macros/macro-crate-use.rs b/src/test/run-pass/macros/macro-crate-use.rs deleted file mode 100644 index 5c37cac9686..00000000000 --- a/src/test/run-pass/macros/macro-crate-use.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/macros/macro-deep_expansion.rs b/src/test/run-pass/macros/macro-deep_expansion.rs deleted file mode 100644 index e13d8e1fc84..00000000000 --- a/src/test/run-pass/macros/macro-deep_expansion.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -macro_rules! foo2 { - () => { - "foo" - } -} - -macro_rules! foo { - () => { - foo2!() - } -} - -fn main() { - assert_eq!(concat!(foo!(), "bar"), "foobar") -} diff --git a/src/test/run-pass/macros/macro-delimiter-significance.rs b/src/test/run-pass/macros/macro-delimiter-significance.rs deleted file mode 100644 index 89f222b0530..00000000000 --- a/src/test/run-pass/macros/macro-delimiter-significance.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - vec![1_usize, 2, 3].len(); -} diff --git a/src/test/run-pass/macros/macro-doc-comments.rs b/src/test/run-pass/macros/macro-doc-comments.rs deleted file mode 100644 index fcc64cc0670..00000000000 --- a/src/test/run-pass/macros/macro-doc-comments.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/macros/macro-doc-escapes.rs b/src/test/run-pass/macros/macro-doc-escapes.rs deleted file mode 100644 index ff5a5793b20..00000000000 --- a/src/test/run-pass/macros/macro-doc-escapes.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/macros/macro-doc-raw-str-hashes.rs b/src/test/run-pass/macros/macro-doc-raw-str-hashes.rs deleted file mode 100644 index a003bff3c04..00000000000 --- a/src/test/run-pass/macros/macro-doc-raw-str-hashes.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/macros/macro-export-inner-module.rs b/src/test/run-pass/macros/macro-export-inner-module.rs deleted file mode 100644 index 1f23e90b65c..00000000000 --- a/src/test/run-pass/macros/macro-export-inner-module.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/macros/macro-first-set.rs b/src/test/run-pass/macros/macro-first-set.rs deleted file mode 100644 index a21e4cd201a..00000000000 --- a/src/test/run-pass/macros/macro-first-set.rs +++ /dev/null @@ -1,277 +0,0 @@ -// 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_meta_block { - ($($m:meta)* $b:block) => {}; -} - -test_meta_block!(windows {}); - -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/src/test/run-pass/macros/macro-followed-by-seq.rs b/src/test/run-pass/macros/macro-followed-by-seq.rs deleted file mode 100644 index 71d59d8d31b..00000000000 --- a/src/test/run-pass/macros/macro-followed-by-seq.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/macros/macro-include-items.rs b/src/test/run-pass/macros/macro-include-items.rs deleted file mode 100644 index 332bf59c944..00000000000 --- a/src/test/run-pass/macros/macro-include-items.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/macros/macro-interpolation.rs b/src/test/run-pass/macros/macro-interpolation.rs deleted file mode 100644 index abe1f2aaf15..00000000000 --- a/src/test/run-pass/macros/macro-interpolation.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs deleted file mode 100644 index 8f9dcb94794..00000000000 --- a/src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -macro_rules! four { - () => (4) -} - -fn main() { - let _x: [u16; four!()]; -} diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-bound.rs b/src/test/run-pass/macros/macro-lifetime-used-with-bound.rs deleted file mode 100644 index ea3f74c9ada..00000000000 --- a/src/test/run-pass/macros/macro-lifetime-used-with-bound.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/macros/macro-lifetime-used-with-labels.rs b/src/test/run-pass/macros/macro-lifetime-used-with-labels.rs deleted file mode 100644 index 4c4bccbc12b..00000000000 --- a/src/test/run-pass/macros/macro-lifetime-used-with-labels.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass -#![allow(stable_features)] - -#![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 { - 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/src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr b/src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr deleted file mode 100644 index 05418d9bddf..00000000000 --- a/src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: label name `'b` shadows a label name that is already in scope - --> $DIR/macro-lifetime-used-with-labels.rs:21:9 - | -LL | 'b: loop { - | ^^ lifetime 'b already in scope -... -LL | 'b: loop { - | -- first declared here -LL | br2!('b); - | --------- in this macro invocation - diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-static.rs b/src/test/run-pass/macros/macro-lifetime-used-with-static.rs deleted file mode 100644 index 8552c4b8163..00000000000 --- a/src/test/run-pass/macros/macro-lifetime-used-with-static.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/macros/macro-lifetime.rs b/src/test/run-pass/macros/macro-lifetime.rs deleted file mode 100644 index 5931fe00907..00000000000 --- a/src/test/run-pass/macros/macro-lifetime.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/macros/macro-literal.rs b/src/test/run-pass/macros/macro-literal.rs deleted file mode 100644 index e08d0a67b43..00000000000 --- a/src/test/run-pass/macros/macro-literal.rs +++ /dev/null @@ -1,133 +0,0 @@ -// 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/src/test/run-pass/macros/macro-meta-items.rs b/src/test/run-pass/macros/macro-meta-items.rs deleted file mode 100644 index 4cbc252aebf..00000000000 --- a/src/test/run-pass/macros/macro-meta-items.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/macros/macro-method-issue-4621.rs b/src/test/run-pass/macros/macro-method-issue-4621.rs deleted file mode 100644 index 342fad5f62e..00000000000 --- a/src/test/run-pass/macros/macro-method-issue-4621.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/macros/macro-multiple-items.rs b/src/test/run-pass/macros/macro-multiple-items.rs deleted file mode 100644 index 3b6dfd9bc5e..00000000000 --- a/src/test/run-pass/macros/macro-multiple-items.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -macro_rules! make_foo { - () => ( - struct Foo; - - impl Foo { - fn bar(&self) {} - } - ) -} - -make_foo!(); - -pub fn main() { - Foo.bar() -} diff --git a/src/test/run-pass/macros/macro-named-default.rs b/src/test/run-pass/macros/macro-named-default.rs deleted file mode 100644 index 9b6cd191640..00000000000 --- a/src/test/run-pass/macros/macro-named-default.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -macro_rules! default { - ($($x:tt)*) => { $($x)* } -} - -default! { - struct A; -} - -impl A { - default! { - fn foo(&self) {} - } -} - -fn main() { - A.foo(); -} diff --git a/src/test/run-pass/macros/macro-nested_definition_issue-31946.rs b/src/test/run-pass/macros/macro-nested_definition_issue-31946.rs deleted file mode 100644 index a83c5b2e44f..00000000000 --- a/src/test/run-pass/macros/macro-nested_definition_issue-31946.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -fn main() { - println!("{}", { - macro_rules! foo { - ($name:expr) => { concat!("hello ", $name) } - } - foo!("rust") - }); -} diff --git a/src/test/run-pass/macros/macro-nested_expr.rs b/src/test/run-pass/macros/macro-nested_expr.rs deleted file mode 100644 index f1433cbf4f9..00000000000 --- a/src/test/run-pass/macros/macro-nested_expr.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/macros/macro-nested_stmt_macros.rs b/src/test/run-pass/macros/macro-nested_stmt_macros.rs deleted file mode 100644 index 5d4758a0c7b..00000000000 --- a/src/test/run-pass/macros/macro-nested_stmt_macros.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/macros/macro-nt-list.rs b/src/test/run-pass/macros/macro-nt-list.rs deleted file mode 100644 index 36aa74f0825..00000000000 --- a/src/test/run-pass/macros/macro-nt-list.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/macros/macro-of-higher-order.rs b/src/test/run-pass/macros/macro-of-higher-order.rs deleted file mode 100644 index ec551d6cdbc..00000000000 --- a/src/test/run-pass/macros/macro-of-higher-order.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/macros/macro-pat-follow.rs b/src/test/run-pass/macros/macro-pat-follow.rs deleted file mode 100644 index 8673cf79467..00000000000 --- a/src/test/run-pass/macros/macro-pat-follow.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/macros/macro-pat-neg-lit.rs b/src/test/run-pass/macros/macro-pat-neg-lit.rs deleted file mode 100644 index 79c68fd2541..00000000000 --- a/src/test/run-pass/macros/macro-pat-neg-lit.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/macros/macro-pat.rs b/src/test/run-pass/macros/macro-pat.rs deleted file mode 100644 index baf816e53ea..00000000000 --- a/src/test/run-pass/macros/macro-pat.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/macros/macro-path.rs b/src/test/run-pass/macros/macro-path.rs deleted file mode 100644 index be59d8d139b..00000000000 --- a/src/test/run-pass/macros/macro-path.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/macros/macro-pub-matcher.rs b/src/test/run-pass/macros/macro-pub-matcher.rs deleted file mode 100644 index c02e6794edb..00000000000 --- a/src/test/run-pass/macros/macro-pub-matcher.rs +++ /dev/null @@ -1,118 +0,0 @@ -// 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/src/test/run-pass/macros/macro-seq-followed-by-seq.rs b/src/test/run-pass/macros/macro-seq-followed-by-seq.rs deleted file mode 100644 index 8f0f4fd4a0d..00000000000 --- a/src/test/run-pass/macros/macro-seq-followed-by-seq.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/macros/macro-stmt.rs b/src/test/run-pass/macros/macro-stmt.rs deleted file mode 100644 index c9a0b879a0f..00000000000 --- a/src/test/run-pass/macros/macro-stmt.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs b/src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs deleted file mode 100644 index 528d0b28bf6..00000000000 --- a/src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/macros/macro-tt-followed-by-seq.rs b/src/test/run-pass/macros/macro-tt-followed-by-seq.rs deleted file mode 100644 index 90131ebd920..00000000000 --- a/src/test/run-pass/macros/macro-tt-followed-by-seq.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/macros/macro-use-all-and-none.rs b/src/test/run-pass/macros/macro-use-all-and-none.rs deleted file mode 100644 index 5fdcda0f78a..00000000000 --- a/src/test/run-pass/macros/macro-use-all-and-none.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// aux-build:two_macros.rs - -#[macro_use] -#[macro_use()] -extern crate two_macros; - -pub fn main() { - macro_one!(); - macro_two!(); -} diff --git a/src/test/run-pass/macros/macro-use-all-and-none.stderr b/src/test/run-pass/macros/macro-use-all-and-none.stderr deleted file mode 100644 index ce12a539541..00000000000 --- a/src/test/run-pass/macros/macro-use-all-and-none.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: unused attribute - --> $DIR/macro-use-all-and-none.rs:5:1 - | -LL | #[macro_use()] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_attributes)]` on by default - diff --git a/src/test/run-pass/macros/macro-use-all.rs b/src/test/run-pass/macros/macro-use-all.rs deleted file mode 100644 index 48c7b77e579..00000000000 --- a/src/test/run-pass/macros/macro-use-all.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:two_macros.rs - -#[macro_use] -extern crate two_macros; - -pub fn main() { - macro_one!(); - macro_two!(); -} diff --git a/src/test/run-pass/macros/macro-use-both.rs b/src/test/run-pass/macros/macro-use-both.rs deleted file mode 100644 index ed5d1312f96..00000000000 --- a/src/test/run-pass/macros/macro-use-both.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/macros/macro-use-one.rs b/src/test/run-pass/macros/macro-use-one.rs deleted file mode 100644 index f74795e68dc..00000000000 --- a/src/test/run-pass/macros/macro-use-one.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// aux-build:two_macros.rs - -#[macro_use(macro_two)] -extern crate two_macros; - -pub fn main() { - macro_two!(); -} diff --git a/src/test/run-pass/macros/macro-with-attrs1.rs b/src/test/run-pass/macros/macro-with-attrs1.rs deleted file mode 100644 index 4e943b224cd..00000000000 --- a/src/test/run-pass/macros/macro-with-attrs1.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/macros/macro-with-attrs2.rs b/src/test/run-pass/macros/macro-with-attrs2.rs deleted file mode 100644 index 78c40810207..00000000000 --- a/src/test/run-pass/macros/macro-with-attrs2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/macros/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macros/macro-with-braces-in-expr-position.rs deleted file mode 100644 index f7d87434ded..00000000000 --- a/src/test/run-pass/macros/macro-with-braces-in-expr-position.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/macros/macro_with_super_2.rs b/src/test/run-pass/macros/macro_with_super_2.rs deleted file mode 100644 index 2901a74f612..00000000000 --- a/src/test/run-pass/macros/macro_with_super_2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/macros/meta-variable-misuse.rs b/src/test/run-pass/macros/meta-variable-misuse.rs deleted file mode 100644 index 99a2f940176..00000000000 --- a/src/test/run-pass/macros/meta-variable-misuse.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/macros/parse-complex-macro-invoc-op.rs b/src/test/run-pass/macros/parse-complex-macro-invoc-op.rs deleted file mode 100644 index 8fef9b0ed87..00000000000 --- a/src/test/run-pass/macros/parse-complex-macro-invoc-op.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/macros/paths-in-macro-invocations.rs b/src/test/run-pass/macros/paths-in-macro-invocations.rs deleted file mode 100644 index 4f745b85c2f..00000000000 --- a/src/test/run-pass/macros/paths-in-macro-invocations.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass -#![allow(dead_code)] -// aux-build:two_macros.rs - -extern crate 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/src/test/run-pass/macros/pub-item-inside-macro.rs b/src/test/run-pass/macros/pub-item-inside-macro.rs deleted file mode 100644 index d07681453a2..00000000000 --- a/src/test/run-pass/macros/pub-item-inside-macro.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -// Issue #14660 - -// pretty-expanded FIXME #23616 - -mod bleh { - macro_rules! foo { - () => { - pub fn bar() { } - } - } - - foo!(); -} - -fn main() { - bleh::bar(); -} diff --git a/src/test/run-pass/macros/pub-method-inside-macro.rs b/src/test/run-pass/macros/pub-method-inside-macro.rs deleted file mode 100644 index bc918c7a4dc..00000000000 --- a/src/test/run-pass/macros/pub-method-inside-macro.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/macros/semi-after-macro-ty.rs b/src/test/run-pass/macros/semi-after-macro-ty.rs deleted file mode 100644 index f83ace8fada..00000000000 --- a/src/test/run-pass/macros/semi-after-macro-ty.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -macro_rules! foo { - ($t:ty; $p:path;) => {} -} - -fn main() { - foo!(i32; i32;); -} diff --git a/src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs b/src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs deleted file mode 100644 index 3ab50db0ea1..00000000000 --- a/src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/macros/syntax-extension-cfg.rs b/src/test/run-pass/macros/syntax-extension-cfg.rs deleted file mode 100644 index 2e929fc1dfa..00000000000 --- a/src/test/run-pass/macros/syntax-extension-cfg.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment b/src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment deleted file mode 100644 index d752015a4dc..00000000000 --- a/src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment +++ /dev/null @@ -1,7 +0,0 @@ -/* this is for run-pass/syntax-extension-source-utils.rs */ - -{ - assert!(file!().ends_with("includeme.fragment")); - assert_eq!(line!(), 5u32); - format!("victory robot {}", line!()) -} diff --git a/src/test/run-pass/macros/syntax-extension-source-utils.rs b/src/test/run-pass/macros/syntax-extension-source-utils.rs deleted file mode 100644 index 7e46260d516..00000000000 --- a/src/test/run-pass/macros/syntax-extension-source-utils.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/macros/try-macro.rs b/src/test/run-pass/macros/try-macro.rs deleted file mode 100644 index 83b30a8b7ba..00000000000 --- a/src/test/run-pass/macros/try-macro.rs +++ /dev/null @@ -1,48 +0,0 @@ -// run-pass -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/src/test/run-pass/macros/two-macro-use.rs b/src/test/run-pass/macros/two-macro-use.rs deleted file mode 100644 index 07022bb01e3..00000000000 --- a/src/test/run-pass/macros/two-macro-use.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/macros/type-macros-hlist.rs b/src/test/run-pass/macros/type-macros-hlist.rs deleted file mode 100644 index 77d866cea9c..00000000000 --- a/src/test/run-pass/macros/type-macros-hlist.rs +++ /dev/null @@ -1,78 +0,0 @@ -// 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/src/test/run-pass/macros/type-macros-simple.rs b/src/test/run-pass/macros/type-macros-simple.rs deleted file mode 100644 index dd3ad2ef0ac..00000000000 --- a/src/test/run-pass/macros/type-macros-simple.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs b/src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs deleted file mode 100644 index f2b089b74b5..00000000000 --- a/src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/macros/use-macro-self.rs b/src/test/run-pass/macros/use-macro-self.rs deleted file mode 100644 index 06464ab0bc9..00000000000 --- a/src/test/run-pass/macros/use-macro-self.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/max-min-classes.rs b/src/test/run-pass/max-min-classes.rs deleted file mode 100644 index f9a39e486da..00000000000 --- a/src/test/run-pass/max-min-classes.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/methods/auxiliary/method_self_arg1.rs b/src/test/run-pass/methods/auxiliary/method_self_arg1.rs deleted file mode 100644 index 8258fdd9ab9..00000000000 --- a/src/test/run-pass/methods/auxiliary/method_self_arg1.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![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/src/test/run-pass/methods/auxiliary/method_self_arg2.rs b/src/test/run-pass/methods/auxiliary/method_self_arg2.rs deleted file mode 100644 index 94a4a016c3e..00000000000 --- a/src/test/run-pass/methods/auxiliary/method_self_arg2.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![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/src/test/run-pass/methods/method-argument-inference-associated-type.rs b/src/test/run-pass/methods/method-argument-inference-associated-type.rs deleted file mode 100644 index acd4a8465b0..00000000000 --- a/src/test/run-pass/methods/method-argument-inference-associated-type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs deleted file mode 100644 index f2ace32c6b6..00000000000 --- a/src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs deleted file mode 100644 index daff037b27b..00000000000 --- a/src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs b/src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs deleted file mode 100644 index 9c0b952849e..00000000000 --- a/src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs b/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs deleted file mode 100644 index af362efe15c..00000000000 --- a/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/methods/method-projection.rs b/src/test/run-pass/methods/method-projection.rs deleted file mode 100644 index cf33d53968b..00000000000 --- a/src/test/run-pass/methods/method-projection.rs +++ /dev/null @@ -1,70 +0,0 @@ -// 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/src/test/run-pass/methods/method-recursive-blanket-impl.rs b/src/test/run-pass/methods/method-recursive-blanket-impl.rs deleted file mode 100644 index a2db75b4e85..00000000000 --- a/src/test/run-pass/methods/method-recursive-blanket-impl.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/methods/method-self-arg-aux1.rs b/src/test/run-pass/methods/method-self-arg-aux1.rs deleted file mode 100644 index 9e38ff7de34..00000000000 --- a/src/test/run-pass/methods/method-self-arg-aux1.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/methods/method-self-arg-aux2.rs b/src/test/run-pass/methods/method-self-arg-aux2.rs deleted file mode 100644 index 8e70399d047..00000000000 --- a/src/test/run-pass/methods/method-self-arg-aux2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/methods/method-self-arg-trait.rs b/src/test/run-pass/methods/method-self-arg-trait.rs deleted file mode 100644 index 227b1eab25d..00000000000 --- a/src/test/run-pass/methods/method-self-arg-trait.rs +++ /dev/null @@ -1,69 +0,0 @@ -// 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/src/test/run-pass/methods/method-self-arg.rs b/src/test/run-pass/methods/method-self-arg.rs deleted file mode 100644 index 2d25b0dbad1..00000000000 --- a/src/test/run-pass/methods/method-self-arg.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs b/src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs deleted file mode 100644 index b768620cd3a..00000000000 --- a/src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs b/src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs deleted file mode 100644 index 8af3dcf5c3d..00000000000 --- a/src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs b/src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs deleted file mode 100644 index d820d2ad08a..00000000000 --- a/src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/methods/method-where-clause.rs b/src/test/run-pass/methods/method-where-clause.rs deleted file mode 100644 index 01692abf9b6..00000000000 --- a/src/test/run-pass/methods/method-where-clause.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/mid-path-type-params.rs b/src/test/run-pass/mid-path-type-params.rs deleted file mode 100644 index a8128207c80..00000000000 --- a/src/test/run-pass/mid-path-type-params.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/minmax-stability-issue-23687.rs b/src/test/run-pass/minmax-stability-issue-23687.rs deleted file mode 100644 index 9100bfbde95..00000000000 --- a/src/test/run-pass/minmax-stability-issue-23687.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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/src/test/run-pass/mir/auxiliary/mir_external_refs.rs b/src/test/run-pass/mir/auxiliary/mir_external_refs.rs deleted file mode 100644 index 9fd58f1d714..00000000000 --- a/src/test/run-pass/mir/auxiliary/mir_external_refs.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs b/src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs deleted file mode 100644 index 1bd16dc43e1..00000000000 --- a/src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs b/src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs deleted file mode 100644 index e930a4d1ccd..00000000000 --- a/src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs b/src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs deleted file mode 100644 index 8f570dbd4ad..00000000000 --- a/src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs b/src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs deleted file mode 100644 index bdd9321afd7..00000000000 --- a/src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/mir/mir_adt_construction.rs b/src/test/run-pass/mir/mir_adt_construction.rs deleted file mode 100644 index 9fb5896de6b..00000000000 --- a/src/test/run-pass/mir/mir_adt_construction.rs +++ /dev/null @@ -1,92 +0,0 @@ -// 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/src/test/run-pass/mir/mir_ascription_coercion.rs b/src/test/run-pass/mir/mir_ascription_coercion.rs deleted file mode 100644 index 0ebd20e97d7..00000000000 --- a/src/test/run-pass/mir/mir_ascription_coercion.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/mir/mir_augmented_assignments.rs b/src/test/run-pass/mir/mir_augmented_assignments.rs deleted file mode 100644 index 44454f8f417..00000000000 --- a/src/test/run-pass/mir/mir_augmented_assignments.rs +++ /dev/null @@ -1,160 +0,0 @@ -// 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/src/test/run-pass/mir/mir_autoderef.rs b/src/test/run-pass/mir/mir_autoderef.rs deleted file mode 100644 index a0e615a7387..00000000000 --- a/src/test/run-pass/mir/mir_autoderef.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/mir/mir_boxing.rs b/src/test/run-pass/mir/mir_boxing.rs deleted file mode 100644 index 83e1cfb640a..00000000000 --- a/src/test/run-pass/mir/mir_boxing.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -fn test() -> Box { - box 42 -} - -fn main() { - assert_eq!(*test(), 42); -} diff --git a/src/test/run-pass/mir/mir_build_match_comparisons.rs b/src/test/run-pass/mir/mir_build_match_comparisons.rs deleted file mode 100644 index 04570055763..00000000000 --- a/src/test/run-pass/mir/mir_build_match_comparisons.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/mir/mir_call_with_associated_type.rs b/src/test/run-pass/mir/mir_call_with_associated_type.rs deleted file mode 100644 index 7103533e1da..00000000000 --- a/src/test/run-pass/mir/mir_call_with_associated_type.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/mir/mir_calls_to_shims.rs b/src/test/run-pass/mir/mir_calls_to_shims.rs deleted file mode 100644 index 6f13d5612ce..00000000000 --- a/src/test/run-pass/mir/mir_calls_to_shims.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/mir/mir_cast_fn_ret.rs b/src/test/run-pass/mir/mir_cast_fn_ret.rs deleted file mode 100644 index 69fd64c1c09..00000000000 --- a/src/test/run-pass/mir/mir_cast_fn_ret.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -pub extern "C" fn tuple2() -> (u16, u8) { - (1, 2) -} - -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/src/test/run-pass/mir/mir_codegen_array.rs b/src/test/run-pass/mir/mir_codegen_array.rs deleted file mode 100644 index 38e443d8e39..00000000000 --- a/src/test/run-pass/mir/mir_codegen_array.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_array_2.rs b/src/test/run-pass/mir/mir_codegen_array_2.rs deleted file mode 100644 index 03d3aa5ade6..00000000000 --- a/src/test/run-pass/mir/mir_codegen_array_2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_call_converging.rs b/src/test/run-pass/mir/mir_codegen_call_converging.rs deleted file mode 100644 index 9c340e4e036..00000000000 --- a/src/test/run-pass/mir/mir_codegen_call_converging.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_calls.rs b/src/test/run-pass/mir/mir_codegen_calls.rs deleted file mode 100644 index fc0db03e3a9..00000000000 --- a/src/test/run-pass/mir/mir_codegen_calls.rs +++ /dev/null @@ -1,191 +0,0 @@ -// 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() -} - -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/src/test/run-pass/mir/mir_codegen_calls_variadic.rs b/src/test/run-pass/mir/mir_codegen_calls_variadic.rs deleted file mode 100644 index dc9fee03b77..00000000000 --- a/src/test/run-pass/mir/mir_codegen_calls_variadic.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_critical_edge.rs b/src/test/run-pass/mir/mir_codegen_critical_edge.rs deleted file mode 100644 index 5c1f1c3b701..00000000000 --- a/src/test/run-pass/mir/mir_codegen_critical_edge.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_spike1.rs b/src/test/run-pass/mir/mir_codegen_spike1.rs deleted file mode 100644 index 90bdd6b4bd7..00000000000 --- a/src/test/run-pass/mir/mir_codegen_spike1.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_switch.rs b/src/test/run-pass/mir/mir_codegen_switch.rs deleted file mode 100644 index d2589ae4ad2..00000000000 --- a/src/test/run-pass/mir/mir_codegen_switch.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/mir/mir_codegen_switchint.rs b/src/test/run-pass/mir/mir_codegen_switchint.rs deleted file mode 100644 index c092a6c31b2..00000000000 --- a/src/test/run-pass/mir/mir_codegen_switchint.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/mir/mir_coercion_casts.rs b/src/test/run-pass/mir/mir_coercion_casts.rs deleted file mode 100644 index 7d761181d80..00000000000 --- a/src/test/run-pass/mir/mir_coercion_casts.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/mir/mir_coercions.rs b/src/test/run-pass/mir/mir_coercions.rs deleted file mode 100644 index f3dcc6b85fd..00000000000 --- a/src/test/run-pass/mir/mir_coercions.rs +++ /dev/null @@ -1,71 +0,0 @@ -// 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/src/test/run-pass/mir/mir_constval_adts.rs b/src/test/run-pass/mir/mir_constval_adts.rs deleted file mode 100644 index ee9d73451f4..00000000000 --- a/src/test/run-pass/mir/mir_constval_adts.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/mir/mir_drop_order.rs b/src/test/run-pass/mir/mir_drop_order.rs deleted file mode 100644 index 2949437b1e4..00000000000 --- a/src/test/run-pass/mir/mir_drop_order.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/mir/mir_early_return_scope.rs b/src/test/run-pass/mir/mir_early_return_scope.rs deleted file mode 100644 index a696471c361..00000000000 --- a/src/test/run-pass/mir/mir_early_return_scope.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/mir/mir_fat_ptr.rs b/src/test/run-pass/mir/mir_fat_ptr.rs deleted file mode 100644 index fb34de62f31..00000000000 --- a/src/test/run-pass/mir/mir_fat_ptr.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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/src/test/run-pass/mir/mir_fat_ptr_drop.rs b/src/test/run-pass/mir/mir_fat_ptr_drop.rs deleted file mode 100644 index d865c3499b2..00000000000 --- a/src/test/run-pass/mir/mir_fat_ptr_drop.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/mir/mir_heavy_promoted.rs b/src/test/run-pass/mir/mir_heavy_promoted.rs deleted file mode 100644 index 092299880e2..00000000000 --- a/src/test/run-pass/mir/mir_heavy_promoted.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/mir/mir_match_arm_guard.rs b/src/test/run-pass/mir/mir_match_arm_guard.rs deleted file mode 100644 index 65e4ed041bb..00000000000 --- a/src/test/run-pass/mir/mir_match_arm_guard.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/mir/mir_match_test.rs b/src/test/run-pass/mir/mir_match_test.rs deleted file mode 100644 index 1f96d6737e0..00000000000 --- a/src/test/run-pass/mir/mir_match_test.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![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/src/test/run-pass/mir/mir_misc_casts.rs b/src/test/run-pass/mir/mir_misc_casts.rs deleted file mode 100644 index 2e7fbeee5da..00000000000 --- a/src/test/run-pass/mir/mir_misc_casts.rs +++ /dev/null @@ -1,320 +0,0 @@ -// 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/src/test/run-pass/mir/mir_overflow_off.rs b/src/test/run-pass/mir/mir_overflow_off.rs deleted file mode 100644 index 922ec36e531..00000000000 --- a/src/test/run-pass/mir/mir_overflow_off.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/mir/mir_raw_fat_ptr.rs b/src/test/run-pass/mir/mir_raw_fat_ptr.rs deleted file mode 100644 index 6583852aa9b..00000000000 --- a/src/test/run-pass/mir/mir_raw_fat_ptr.rs +++ /dev/null @@ -1,158 +0,0 @@ -// run-pass -// check raw fat pointer ops in mir -// FIXME: please improve this when we get monomorphization support - -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() { - 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 _)); -} diff --git a/src/test/run-pass/mir/mir_refs_correct.rs b/src/test/run-pass/mir/mir_refs_correct.rs deleted file mode 100644 index 729db2d25f5..00000000000 --- a/src/test/run-pass/mir/mir_refs_correct.rs +++ /dev/null @@ -1,209 +0,0 @@ -// 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/src/test/run-pass/mir/mir_small_agg_arg.rs b/src/test/run-pass/mir/mir_small_agg_arg.rs deleted file mode 100644 index 5a22a0420c5..00000000000 --- a/src/test/run-pass/mir/mir_small_agg_arg.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unused_variables)] -fn foo((x, y): (i8, i8)) { -} - -fn main() { - foo((0, 1)); -} diff --git a/src/test/run-pass/mir/mir_static_subtype.rs b/src/test/run-pass/mir/mir_static_subtype.rs deleted file mode 100644 index d471b8f149d..00000000000 --- a/src/test/run-pass/mir/mir_static_subtype.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/mir/mir_struct_with_assoc_ty.rs b/src/test/run-pass/mir/mir_struct_with_assoc_ty.rs deleted file mode 100644 index 26d026bdfdd..00000000000 --- a/src/test/run-pass/mir/mir_struct_with_assoc_ty.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/mir/mir_temp_promotions.rs b/src/test/run-pass/mir/mir_temp_promotions.rs deleted file mode 100644 index 845dc4c0444..00000000000 --- a/src/test/run-pass/mir/mir_temp_promotions.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/mir/mir_void_return.rs b/src/test/run-pass/mir/mir_void_return.rs deleted file mode 100644 index d257affc268..00000000000 --- a/src/test/run-pass/mir/mir_void_return.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -fn mir() -> (){ - let x = 1; - let mut y = 0; - while y < x { - y += 1 - } -} - -pub fn main() { - mir(); -} diff --git a/src/test/run-pass/mir/mir_void_return_2.rs b/src/test/run-pass/mir/mir_void_return_2.rs deleted file mode 100644 index a1fb0a7db17..00000000000 --- a/src/test/run-pass/mir/mir_void_return_2.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -fn nil() {} - -fn mir(){ - nil() -} - -pub fn main() { - mir(); -} diff --git a/src/test/run-pass/modules/auxiliary/two_macros_2.rs b/src/test/run-pass/modules/auxiliary/two_macros_2.rs deleted file mode 100644 index 8ad2c0f1275..00000000000 --- a/src/test/run-pass/modules/auxiliary/two_macros_2.rs +++ /dev/null @@ -1,3 +0,0 @@ -macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } - -macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } diff --git a/src/test/run-pass/modules/mod-inside-fn.rs b/src/test/run-pass/modules/mod-inside-fn.rs deleted file mode 100644 index 93050c8919a..00000000000 --- a/src/test/run-pass/modules/mod-inside-fn.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -fn f() -> isize { - mod m { - pub fn g() -> isize { 720 } - } - - m::g() -} - -pub fn main() { - assert_eq!(f(), 720); -} diff --git a/src/test/run-pass/modules/mod-view-items.rs b/src/test/run-pass/modules/mod-view-items.rs deleted file mode 100644 index db2b303668b..00000000000 --- a/src/test/run-pass/modules/mod-view-items.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_implicit.rs b/src/test/run-pass/modules/mod_dir_implicit.rs deleted file mode 100644 index d6ea6a98bda..00000000000 --- a/src/test/run-pass/modules/mod_dir_implicit.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_implicit_aux/compiletest-ignore-dir b/src/test/run-pass/modules/mod_dir_implicit_aux/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs b/src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs deleted file mode 100644 index 4f1eb85e4cc..00000000000 --- a/src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -// run-pass -pub fn foo() -> isize { 10 } diff --git a/src/test/run-pass/modules/mod_dir_path.rs b/src/test/run-pass/modules/mod_dir_path.rs deleted file mode 100644 index 70f592d0c0e..00000000000 --- a/src/test/run-pass/modules/mod_dir_path.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_path2.rs b/src/test/run-pass/modules/mod_dir_path2.rs deleted file mode 100644 index c3e3e1d639e..00000000000 --- a/src/test/run-pass/modules/mod_dir_path2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_path3.rs b/src/test/run-pass/modules/mod_dir_path3.rs deleted file mode 100644 index fed70c1bc98..00000000000 --- a/src/test/run-pass/modules/mod_dir_path3.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_path_multi.rs b/src/test/run-pass/modules/mod_dir_path_multi.rs deleted file mode 100644 index 2b805141a63..00000000000 --- a/src/test/run-pass/modules/mod_dir_path_multi.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_recursive.rs b/src/test/run-pass/modules/mod_dir_recursive.rs deleted file mode 100644 index b109d13d164..00000000000 --- a/src/test/run-pass/modules/mod_dir_recursive.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_simple.rs b/src/test/run-pass/modules/mod_dir_simple.rs deleted file mode 100644 index 1d92c968a8f..00000000000 --- a/src/test/run-pass/modules/mod_dir_simple.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/modules/mod_dir_simple/compiletest-ignore-dir b/src/test/run-pass/modules/mod_dir_simple/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs b/src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs deleted file mode 100644 index f96b546aa2f..00000000000 --- a/src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass -#[path = "test.rs"] -pub mod test; diff --git a/src/test/run-pass/modules/mod_dir_simple/test.rs b/src/test/run-pass/modules/mod_dir_simple/test.rs deleted file mode 100644 index 4f1eb85e4cc..00000000000 --- a/src/test/run-pass/modules/mod_dir_simple/test.rs +++ /dev/null @@ -1,2 +0,0 @@ -// run-pass -pub fn foo() -> isize { 10 } diff --git a/src/test/run-pass/modules/mod_file.rs b/src/test/run-pass/modules/mod_file.rs deleted file mode 100644 index 0ca52889e5c..00000000000 --- a/src/test/run-pass/modules/mod_file.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/modules/mod_file_aux.rs b/src/test/run-pass/modules/mod_file_aux.rs deleted file mode 100644 index 6d052272eb3..00000000000 --- a/src/test/run-pass/modules/mod_file_aux.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -// ignore-test Not a test. Used by other tests - -pub fn foo() -> isize { 10 } diff --git a/src/test/run-pass/modules/mod_file_with_path_attr.rs b/src/test/run-pass/modules/mod_file_with_path_attr.rs deleted file mode 100644 index 48e253eadae..00000000000 --- a/src/test/run-pass/modules/mod_file_with_path_attr.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/modules/module-polymorphism3-files/compiletest-ignore-dir b/src/test/run-pass/modules/module-polymorphism3-files/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs b/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs deleted file mode 100644 index 49d2b3d4b85..00000000000 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub type T = f32; diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs b/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs deleted file mode 100644 index e2aad480e3d..00000000000 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub type T = f64; diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs b/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs deleted file mode 100644 index 5828718cddc..00000000000 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub type T = float; diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs deleted file mode 100644 index 5d0612cf8dc..00000000000 --- a/src/test/run-pass/monad.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/monomorphize-abi-alignment.rs b/src/test/run-pass/monomorphize-abi-alignment.rs deleted file mode 100644 index 637b09fc04e..00000000000 --- a/src/test/run-pass/monomorphize-abi-alignment.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs deleted file mode 100644 index bc314a39d8e..00000000000 --- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/moves/move-1-unique.rs b/src/test/run-pass/moves/move-1-unique.rs deleted file mode 100644 index 48baead074a..00000000000 --- a/src/test/run-pass/moves/move-1-unique.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/moves/move-2-unique.rs b/src/test/run-pass/moves/move-2-unique.rs deleted file mode 100644 index 910a88c102f..00000000000 --- a/src/test/run-pass/moves/move-2-unique.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/moves/move-2.rs b/src/test/run-pass/moves/move-2.rs deleted file mode 100644 index 4ad53e96e50..00000000000 --- a/src/test/run-pass/moves/move-2.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/moves/move-3-unique.rs b/src/test/run-pass/moves/move-3-unique.rs deleted file mode 100644 index 55b10e057d8..00000000000 --- a/src/test/run-pass/moves/move-3-unique.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/moves/move-4-unique.rs b/src/test/run-pass/moves/move-4-unique.rs deleted file mode 100644 index 1787caadb7a..00000000000 --- a/src/test/run-pass/moves/move-4-unique.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/moves/move-4.rs b/src/test/run-pass/moves/move-4.rs deleted file mode 100644 index c87c605df77..00000000000 --- a/src/test/run-pass/moves/move-4.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/moves/move-arg-2-unique.rs b/src/test/run-pass/moves/move-arg-2-unique.rs deleted file mode 100644 index fcfd5e14765..00000000000 --- a/src/test/run-pass/moves/move-arg-2-unique.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/moves/move-arg-2.rs b/src/test/run-pass/moves/move-arg-2.rs deleted file mode 100644 index 4cd1f6fe810..00000000000 --- a/src/test/run-pass/moves/move-arg-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/moves/move-arg.rs b/src/test/run-pass/moves/move-arg.rs deleted file mode 100644 index 5942cd89fd9..00000000000 --- a/src/test/run-pass/moves/move-arg.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -fn test(foo: isize) { assert_eq!(foo, 10); } - -pub fn main() { let x = 10; test(x); } diff --git a/src/test/run-pass/moves/move-nullary-fn.rs b/src/test/run-pass/moves/move-nullary-fn.rs deleted file mode 100644 index 14c9262c74d..00000000000 --- a/src/test/run-pass/moves/move-nullary-fn.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/moves/move-out-of-field.rs b/src/test/run-pass/moves/move-out-of-field.rs deleted file mode 100644 index 9f697db4f79..00000000000 --- a/src/test/run-pass/moves/move-out-of-field.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/moves/move-scalar.rs b/src/test/run-pass/moves/move-scalar.rs deleted file mode 100644 index 98bfeb1bc05..00000000000 --- a/src/test/run-pass/moves/move-scalar.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/moves/moves-based-on-type-capture-clause.rs b/src/test/run-pass/moves/moves-based-on-type-capture-clause.rs deleted file mode 100644 index 4a6a4ed281d..00000000000 --- a/src/test/run-pass/moves/moves-based-on-type-capture-clause.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/mpsc_stress.rs b/src/test/run-pass/mpsc_stress.rs deleted file mode 100644 index bce5fdcd119..00000000000 --- a/src/test/run-pass/mpsc_stress.rs +++ /dev/null @@ -1,164 +0,0 @@ -// run-pass -// compile-flags:--test -// ignore-emscripten -// ignore-sgx no thread sleep support - -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 { - } - } -} - - -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/src/test/run-pass/msvc-data-only.rs b/src/test/run-pass/msvc-data-only.rs deleted file mode 100644 index f668b0b0682..00000000000 --- a/src/test/run-pass/msvc-data-only.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs deleted file mode 100644 index e4b41e41806..00000000000 --- a/src/test/run-pass/multi-panic.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/multibyte.rs b/src/test/run-pass/multibyte.rs deleted file mode 100644 index 7e3a577f9f2..00000000000 --- a/src/test/run-pass/multibyte.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// - -// Test that multibyte characters don't crash the compiler -pub fn main() { - println!("마이너스 사인이 없으면"); -} diff --git a/src/test/run-pass/multidispatch-conditional-impl-not-considered.rs b/src/test/run-pass/multidispatch-conditional-impl-not-considered.rs deleted file mode 100644 index f845e198aa5..00000000000 --- a/src/test/run-pass/multidispatch-conditional-impl-not-considered.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/multidispatch1.rs b/src/test/run-pass/multidispatch1.rs deleted file mode 100644 index f2469e1490e..00000000000 --- a/src/test/run-pass/multidispatch1.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/multidispatch2.rs b/src/test/run-pass/multidispatch2.rs deleted file mode 100644 index 20608aabb3b..00000000000 --- a/src/test/run-pass/multidispatch2.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/multiline-comment.rs b/src/test/run-pass/multiline-comment.rs deleted file mode 100644 index 01aaac28232..00000000000 --- a/src/test/run-pass/multiline-comment.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -/* - * This is a multi-line oldcomment. - */ -pub fn main() { } diff --git a/src/test/run-pass/multiple-reprs.rs b/src/test/run-pass/multiple-reprs.rs deleted file mode 100644 index 4be503a0ef4..00000000000 --- a/src/test/run-pass/multiple-reprs.rs +++ /dev/null @@ -1,82 +0,0 @@ -// 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/src/test/run-pass/mut-function-arguments.rs b/src/test/run-pass/mut-function-arguments.rs deleted file mode 100644 index 620d00edbbc..00000000000 --- a/src/test/run-pass/mut-function-arguments.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/mut-vstore-expr.rs b/src/test/run-pass/mut-vstore-expr.rs deleted file mode 100644 index 75b309a4839..00000000000 --- a/src/test/run-pass/mut-vstore-expr.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -pub fn main() { - let _x: &mut [isize] = &mut [ 1, 2, 3 ]; -} diff --git a/src/test/run-pass/mutual-recursion-group.rs b/src/test/run-pass/mutual-recursion-group.rs deleted file mode 100644 index 86b0f1d840e..00000000000 --- a/src/test/run-pass/mutual-recursion-group.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/native-print-no-runtime.rs b/src/test/run-pass/native-print-no-runtime.rs deleted file mode 100644 index f17c9fa6ca9..00000000000 --- a/src/test/run-pass/native-print-no-runtime.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -#![feature(start)] - -#[start] -pub fn main(_: isize, _: *const *const u8) -> isize { - println!("hello"); - 0 -} diff --git a/src/test/run-pass/negative.rs b/src/test/run-pass/negative.rs deleted file mode 100644 index 9601e9118aa..00000000000 --- a/src/test/run-pass/negative.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -pub fn main() { - match -5 { - -5 => {} - _ => { panic!() } - } -} diff --git a/src/test/run-pass/nested-block-comment.rs b/src/test/run-pass/nested-block-comment.rs deleted file mode 100644 index f8dfb5fa8ca..00000000000 --- a/src/test/run-pass/nested-block-comment.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -/* This test checks that nested comments are supported - - /* - This should not panic - */ -*/ - -pub fn main() { -} diff --git a/src/test/run-pass/nested-class.rs b/src/test/run-pass/nested-class.rs deleted file mode 100644 index 303273618e1..00000000000 --- a/src/test/run-pass/nested-class.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/nested-function-names-issue-8587.rs b/src/test/run-pass/nested-function-names-issue-8587.rs deleted file mode 100644 index 8fafd41d9bc..00000000000 --- a/src/test/run-pass/nested-function-names-issue-8587.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/nested_item_main.rs b/src/test/run-pass/nested_item_main.rs deleted file mode 100644 index 2fe00aede00..00000000000 --- a/src/test/run-pass/nested_item_main.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/never-result.rs b/src/test/run-pass/never-result.rs deleted file mode 100644 index 98ce326aa66..00000000000 --- a/src/test/run-pass/never-result.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/never-type-rvalues.rs b/src/test/run-pass/never-type-rvalues.rs deleted file mode 100644 index 9ccc73dbf92..00000000000 --- a/src/test/run-pass/never-type-rvalues.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/never_coercions.rs b/src/test/run-pass/never_coercions.rs deleted file mode 100644 index 105c3863533..00000000000 --- a/src/test/run-pass/never_coercions.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs deleted file mode 100644 index 418cf554b49..00000000000 --- a/src/test/run-pass/new-box-syntax.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/new-box.rs b/src/test/run-pass/new-box.rs deleted file mode 100644 index d11f0d045a7..00000000000 --- a/src/test/run-pass/new-box.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/new-impl-syntax.rs b/src/test/run-pass/new-impl-syntax.rs deleted file mode 100644 index e1f2bea9afa..00000000000 --- a/src/test/run-pass/new-impl-syntax.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/new-import-syntax.rs b/src/test/run-pass/new-import-syntax.rs deleted file mode 100644 index f132ed57ce9..00000000000 --- a/src/test/run-pass/new-import-syntax.rs +++ /dev/null @@ -1,5 +0,0 @@ -// run-pass - -pub fn main() { - println!("Hello world!"); -} diff --git a/src/test/run-pass/new-style-constants.rs b/src/test/run-pass/new-style-constants.rs deleted file mode 100644 index 82ed7b55740..00000000000 --- a/src/test/run-pass/new-style-constants.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -static FOO: isize = 3; - -pub fn main() { - println!("{}", FOO); -} diff --git a/src/test/run-pass/new-unicode-escapes.rs b/src/test/run-pass/new-unicode-escapes.rs deleted file mode 100644 index 850b0de44b7..00000000000 --- a/src/test/run-pass/new-unicode-escapes.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/new-unsafe-pointers.rs b/src/test/run-pass/new-unsafe-pointers.rs deleted file mode 100644 index d99eb4cbd1c..00000000000 --- a/src/test/run-pass/new-unsafe-pointers.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/newlambdas-ret-infer.rs b/src/test/run-pass/newlambdas-ret-infer.rs deleted file mode 100644 index 9b629838ffd..00000000000 --- a/src/test/run-pass/newlambdas-ret-infer.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/newlambdas-ret-infer2.rs b/src/test/run-pass/newlambdas-ret-infer2.rs deleted file mode 100644 index abe31a05f22..00000000000 --- a/src/test/run-pass/newlambdas-ret-infer2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/newlambdas.rs b/src/test/run-pass/newlambdas.rs deleted file mode 100644 index 90de53856c0..00000000000 --- a/src/test/run-pass/newlambdas.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs deleted file mode 100644 index a6a725211ad..00000000000 --- a/src/test/run-pass/newtype-polymorphic.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/newtype-temporary.rs b/src/test/run-pass/newtype-temporary.rs deleted file mode 100644 index 8ee75b2fef1..00000000000 --- a/src/test/run-pass/newtype-temporary.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - -#[derive(PartialEq, Debug)] -struct Foo(usize); - -fn foo() -> Foo { - Foo(42) -} - -pub fn main() { - assert_eq!(foo(), Foo(42)); -} diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs deleted file mode 100644 index f02b66f450f..00000000000 --- a/src/test/run-pass/newtype.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/nil-decl-in-foreign.rs b/src/test/run-pass/nil-decl-in-foreign.rs deleted file mode 100644 index 98422665b9c..00000000000 --- a/src/test/run-pass/nil-decl-in-foreign.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/run-pass/nll/issue-47153-generic-const.rs deleted file mode 100644 index 9f4d57111bb..00000000000 --- a/src/test/run-pass/nll/issue-47153-generic-const.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/nll/issue-47589.rs b/src/test/run-pass/nll/issue-47589.rs deleted file mode 100644 index 280bf081138..00000000000 --- a/src/test/run-pass/nll/issue-47589.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/nll/issue-48623-closure.rs b/src/test/run-pass/nll/issue-48623-closure.rs deleted file mode 100644 index 3f8587eed41..00000000000 --- a/src/test/run-pass/nll/issue-48623-closure.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/nll/issue-48623-generator.rs b/src/test/run-pass/nll/issue-48623-generator.rs deleted file mode 100644 index ba3eccff495..00000000000 --- a/src/test/run-pass/nll/issue-48623-generator.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 }; -} - -fn main() {} diff --git a/src/test/run-pass/nll/issue-50343.rs b/src/test/run-pass/nll/issue-50343.rs deleted file mode 100644 index 55a2d231e19..00000000000 --- a/src/test/run-pass/nll/issue-50343.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![deny(unused_mut)] - -fn main() { - vec![42].iter().map(|_| ()).count(); - vec![(42, 22)].iter().map(|(_x, _y)| ()).count(); -} diff --git a/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs b/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs deleted file mode 100644 index 69d7cdd83a6..00000000000 --- a/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs b/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs deleted file mode 100644 index 941c9eeb411..00000000000 --- a/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/nll/mutating_references.rs b/src/test/run-pass/nll/mutating_references.rs deleted file mode 100644 index eb46b30b6b9..00000000000 --- a/src/test/run-pass/nll/mutating_references.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/nll/process_or_insert_default.rs b/src/test/run-pass/nll/process_or_insert_default.rs deleted file mode 100644 index 84ac9bbd0dd..00000000000 --- a/src/test/run-pass/nll/process_or_insert_default.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs deleted file mode 100644 index e59303d1f78..00000000000 --- a/src/test/run-pass/nll/rc-loop.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/no-core-1.rs b/src/test/run-pass/no-core-1.rs deleted file mode 100644 index 9374f546ac9..00000000000 --- a/src/test/run-pass/no-core-1.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/no-core-2.rs b/src/test/run-pass/no-core-2.rs deleted file mode 100644 index b08e63dc7cf..00000000000 --- a/src/test/run-pass/no-core-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/no-landing-pads.rs b/src/test/run-pass/no-landing-pads.rs deleted file mode 100644 index d9d53210612..00000000000 --- a/src/test/run-pass/no-landing-pads.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -// compile-flags: -Z no-landing-pads -C codegen-units=1 -// ignore-emscripten no threads support - -use std::thread; - -static mut HIT: bool = false; - -struct A; - -impl Drop for A { - fn drop(&mut self) { - unsafe { HIT = true; } - } -} - -fn main() { - thread::spawn(move|| -> () { - let _a = A; - panic!(); - }).join().unwrap_err(); - assert!(unsafe { !HIT }); -} diff --git a/src/test/run-pass/no-std-1.rs b/src/test/run-pass/no-std-1.rs deleted file mode 100644 index 5b59e9b4eb3..00000000000 --- a/src/test/run-pass/no-std-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -#![no_std] - -extern crate std; - -fn main() { - let a = Some("foo"); - a.unwrap(); -} diff --git a/src/test/run-pass/no-std-2.rs b/src/test/run-pass/no-std-2.rs deleted file mode 100644 index 487d41649f4..00000000000 --- a/src/test/run-pass/no-std-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -#![no_std] - -extern crate std; - -fn main() { - let a = core::option::Option::Some("foo"); - a.unwrap(); -} diff --git a/src/test/run-pass/no-std-3.rs b/src/test/run-pass/no-std-3.rs deleted file mode 100644 index f6c4ed5794c..00000000000 --- a/src/test/run-pass/no-std-3.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/no-stdio.rs b/src/test/run-pass/no-stdio.rs deleted file mode 100644 index e72b7b26e22..00000000000 --- a/src/test/run-pass/no-stdio.rs +++ /dev/null @@ -1,120 +0,0 @@ -// 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(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 { - println!("test"); - assert!(io::stdout().write(b"test\n").is_ok()); - assert!(io::stderr().write(b"test\n").is_ok()); - assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); - 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/src/test/run-pass/non-built-in-quote.rs b/src/test/run-pass/non-built-in-quote.rs deleted file mode 100644 index 92efa99e396..00000000000 --- a/src/test/run-pass/non-built-in-quote.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -macro_rules! quote_tokens { () => (()) } - -pub fn main() { - quote_tokens!(); -} diff --git a/src/test/run-pass/non-legacy-modes.rs b/src/test/run-pass/non-legacy-modes.rs deleted file mode 100644 index 38c83e00a6a..00000000000 --- a/src/test/run-pass/non-legacy-modes.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/non_modrs_mods/foors_mod.rs b/src/test/run-pass/non_modrs_mods/foors_mod.rs deleted file mode 100644 index 5bf35fbf7fb..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir b/src/test/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs b/src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs b/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs deleted file mode 100644 index 4d8eb350bd2..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs b/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs deleted file mode 100644 index 4d8eb350bd2..00000000000 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir b/src/test/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs deleted file mode 100644 index 4d8eb350bd2..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs deleted file mode 100644 index 4d8eb350bd2..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs deleted file mode 100644 index c8efa66d665..00000000000 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -pub mod inner_modrs_mod; -pub mod inner_foors_mod; -pub mod inline { - #[path="somename.rs"] - pub mod innie; -} diff --git a/src/test/run-pass/non_modrs_mods/non_modrs_mods.rs b/src/test/run-pass/non_modrs_mods/non_modrs_mods.rs deleted file mode 100644 index f664b0166d8..00000000000 --- a/src/test/run-pass/non_modrs_mods/non_modrs_mods.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs deleted file mode 100644 index 7d5d5b9e5ca..00000000000 --- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod inner_modrs_mod; diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs deleted file mode 100644 index 04585f918fd..00000000000 --- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs deleted file mode 100644 index 4d8eb350bd2..00000000000 --- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub mod innest; diff --git a/src/test/run-pass/nul-characters.rs b/src/test/run-pass/nul-characters.rs deleted file mode 100644 index 11b6e9fe376..00000000000 --- a/src/test/run-pass/nul-characters.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/nullable-pointer-ffi-compat.rs b/src/test/run-pass/nullable-pointer-ffi-compat.rs deleted file mode 100644 index 0647a18c3c4..00000000000 --- a/src/test/run-pass/nullable-pointer-ffi-compat.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs deleted file mode 100644 index 4c6964f294b..00000000000 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ /dev/null @@ -1,73 +0,0 @@ -// 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/src/test/run-pass/nullable-pointer-size.rs b/src/test/run-pass/nullable-pointer-size.rs deleted file mode 100644 index 63a106f1292..00000000000 --- a/src/test/run-pass/nullable-pointer-size.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/arith-0.rs b/src/test/run-pass/numbers-arithmetic/arith-0.rs deleted file mode 100644 index 7943cb908d1..00000000000 --- a/src/test/run-pass/numbers-arithmetic/arith-0.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - - -pub fn main() { - let a: isize = 10; - println!("{}", a); - assert_eq!(a * (a - 1), 90); -} diff --git a/src/test/run-pass/numbers-arithmetic/arith-1.rs b/src/test/run-pass/numbers-arithmetic/arith-1.rs deleted file mode 100644 index c13c8d8b765..00000000000 --- a/src/test/run-pass/numbers-arithmetic/arith-1.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - - -pub fn main() { - let i32_a: isize = 10; - assert_eq!(i32_a, 10); - assert_eq!(i32_a - 10, 0); - assert_eq!(i32_a / 10, 1); - assert_eq!(i32_a - 20, -10); - assert_eq!(i32_a << 10, 10240); - assert_eq!(i32_a << 16, 655360); - assert_eq!(i32_a * 16, 160); - assert_eq!(i32_a * i32_a * i32_a, 1000); - assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000); - assert_eq!(i32_a * i32_a / i32_a * i32_a, 100); - assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640); - let i32_b: isize = 0x10101010; - assert_eq!(i32_b + 1 - 1, i32_b); - assert_eq!(i32_b << 1, i32_b << 1); - assert_eq!(i32_b >> 1, i32_b >> 1); - assert_eq!(i32_b & i32_b << 1, 0); - println!("{}", i32_b | i32_b << 1); - assert_eq!(i32_b | i32_b << 1, 0x30303030); -} diff --git a/src/test/run-pass/numbers-arithmetic/arith-2.rs b/src/test/run-pass/numbers-arithmetic/arith-2.rs deleted file mode 100644 index 46c280677ce..00000000000 --- a/src/test/run-pass/numbers-arithmetic/arith-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - - - -pub fn main() { - let i32_c: isize = 0x10101010; - assert_eq!(i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3), - i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3)); -} diff --git a/src/test/run-pass/numbers-arithmetic/arith-unsigned.rs b/src/test/run-pass/numbers-arithmetic/arith-unsigned.rs deleted file mode 100644 index ad57d9f8645..00000000000 --- a/src/test/run-pass/numbers-arithmetic/arith-unsigned.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/div-mod.rs b/src/test/run-pass/numbers-arithmetic/div-mod.rs deleted file mode 100644 index acb92a7df73..00000000000 --- a/src/test/run-pass/numbers-arithmetic/div-mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs b/src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs deleted file mode 100644 index d210abdf499..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs +++ /dev/null @@ -1,53 +0,0 @@ -// run-pass -// ignore-emscripten no i128 support - -#![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/src/test/run-pass/numbers-arithmetic/float-literal-inference.rs b/src/test/run-pass/numbers-arithmetic/float-literal-inference.rs deleted file mode 100644 index c4645e4f8ff..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float-literal-inference.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float-nan.rs b/src/test/run-pass/numbers-arithmetic/float-nan.rs deleted file mode 100644 index ee87b8cccfe..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float-nan.rs +++ /dev/null @@ -1,83 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float-signature.rs b/src/test/run-pass/numbers-arithmetic/float-signature.rs deleted file mode 100644 index d47280ea2e7..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float-signature.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float.rs b/src/test/run-pass/numbers-arithmetic/float.rs deleted file mode 100644 index d55c05857b6..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float2.rs b/src/test/run-pass/numbers-arithmetic/float2.rs deleted file mode 100644 index b1bcf8da5a3..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/float_math.rs b/src/test/run-pass/numbers-arithmetic/float_math.rs deleted file mode 100644 index a2902ee5608..00000000000 --- a/src/test/run-pass/numbers-arithmetic/float_math.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/floatlits.rs b/src/test/run-pass/numbers-arithmetic/floatlits.rs deleted file mode 100644 index 07049af315b..00000000000 --- a/src/test/run-pass/numbers-arithmetic/floatlits.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/i128-ffi.rs b/src/test/run-pass/numbers-arithmetic/i128-ffi.rs deleted file mode 100644 index 19edf9779f3..00000000000 --- a/src/test/run-pass/numbers-arithmetic/i128-ffi.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/i128.rs b/src/test/run-pass/numbers-arithmetic/i128.rs deleted file mode 100644 index ea0ef95e4f1..00000000000 --- a/src/test/run-pass/numbers-arithmetic/i128.rs +++ /dev/null @@ -1,110 +0,0 @@ -// run-pass -#![allow(overflowing_literals)] - -// ignore-emscripten i128 doesn't work - - -#![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_value()); - 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/src/test/run-pass/numbers-arithmetic/i32-sub.rs b/src/test/run-pass/numbers-arithmetic/i32-sub.rs deleted file mode 100644 index 56df772b4e1..00000000000 --- a/src/test/run-pass/numbers-arithmetic/i32-sub.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - - - - -pub fn main() { let mut x: i32 = -400; x = 0 - x; assert_eq!(x, 400); } diff --git a/src/test/run-pass/numbers-arithmetic/i8-incr.rs b/src/test/run-pass/numbers-arithmetic/i8-incr.rs deleted file mode 100644 index 718d259f735..00000000000 --- a/src/test/run-pass/numbers-arithmetic/i8-incr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs b/src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs deleted file mode 100644 index 2bc018445db..00000000000 --- a/src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// compile-flags: -Z force-overflow-checks=on -// ignore-emscripten no threads support - -use std::thread; - -fn main() { - assert!(thread::spawn(|| i8::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i16::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i32::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i64::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| isize::min_value().abs()).join().is_err()); -} diff --git a/src/test/run-pass/numbers-arithmetic/int.rs b/src/test/run-pass/numbers-arithmetic/int.rs deleted file mode 100644 index b496a70a6fe..00000000000 --- a/src/test/run-pass/numbers-arithmetic/int.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - - - -// pretty-expanded FIXME #23616 - -pub fn main() { let _x: isize = 10; } diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs b/src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs deleted file mode 100644 index 8f61ea17a12..00000000000 --- a/src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs deleted file mode 100644 index 80248dc223d..00000000000 --- a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn foo(_: *const ()) {} - -fn main() { - let a = 3; - foo(&a as *const _ as *const ()); -} diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs b/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs deleted file mode 100644 index bec718a3c6a..00000000000 --- a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() { - println!("{}", std::mem::size_of_val(&1)); -} diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs b/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs deleted file mode 100644 index d177ced1a69..00000000000 --- a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs deleted file mode 100644 index e9927304f23..00000000000 --- a/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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_value()).next_power_of_two() - }); - assert!(r.is_err()); - - let r = panic::catch_unwind(|| { - (($t::max_value() >> 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/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs b/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs deleted file mode 100644 index 982cd97c50a..00000000000 --- a/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/num-wrapping.rs b/src/test/run-pass/numbers-arithmetic/num-wrapping.rs deleted file mode 100644 index 9a01549ecd2..00000000000 --- a/src/test/run-pass/numbers-arithmetic/num-wrapping.rs +++ /dev/null @@ -1,447 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs b/src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs deleted file mode 100644 index 5798c2591a0..00000000000 --- a/src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs b/src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs deleted file mode 100644 index a3b8ff58a73..00000000000 --- a/src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![allow(const_err)] - -// compile-flags: -O - -fn main() { - let x = &(0u32 - 1); - assert_eq!(*x, u32::max_value()) -} diff --git a/src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs b/src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs deleted file mode 100644 index f13964fb386..00000000000 --- a/src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs +++ /dev/null @@ -1,135 +0,0 @@ -// run-pass -// Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. -// compile-flags: -Z saturating-float-casts - -#![feature(test, stmt_expr_attributes)] -#![deny(overflowing_literals)] -extern crate test; - -use std::{f32, f64}; -use std::{u8, i8, u16, i16, u32, i32, u64, i64}; -#[cfg(not(target_os="emscripten"))] -use std::{u128, i128}; -use test::black_box; - -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)); - ); - - ($fval:expr, f* -> $ity:ident, $ival:expr) => ( - test!($fval, f32 -> $ity, $ival); - test!($fval, f64 -> $ity, $ival); - ) -} - -// This macro tests const eval in addition to run-time evaluation. -// If and when saturating casts are adopted, this macro should be merged with test!() to ensure -// that run-time and const eval agree on inputs that currently trigger a const eval error. -macro_rules! test_c { - ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ - test!($val, $src_ty -> $dest_ty, $expected); - { - 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_c!($fval, f32 -> $ity, $ival); - test_c!($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_c!(0., $fty -> $ity, 0); - test_c!($fty::MIN_POSITIVE, $fty -> $ity, 0); - test!(-0.9, $fty -> $ity, 0); - test_c!(1., $fty -> $ity, 1); - test_c!(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)+); - }) -} - -pub fn main() { - 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_c!(254., f* -> u8, 254); - test!(256., f* -> u8, 255); - - // # i8 - test_c!(-127., f* -> i8, -127); - test!(-129., f* -> i8, -128); - test_c!(126., f* -> i8, 126); - test!(128., f* -> i8, 127); - - // # i32 - // -2147483648. is i32::MIN (exactly) - test_c!(-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_c!(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_c!(-2147483520., f* -> i32, -2147483520); - - // # u32 - // round(MAX) and nextUp(round(MAX)) - test_c!(4294967040., f* -> u32, 4294967040); - test!(4294967296., f* -> u32, 4294967295); - - // # u128 - #[cfg(not(target_os="emscripten"))] - { - // float->int: - test_c!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000); - // nextDown(f32::MAX) = 2^128 - 2 * 2^104 - const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; - test_c!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000); - } -} diff --git a/src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs b/src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs deleted file mode 100644 index 939eb974612..00000000000 --- a/src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs +++ /dev/null @@ -1,100 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/shift-various-types.rs b/src/test/run-pass/numbers-arithmetic/shift-various-types.rs deleted file mode 100644 index 473bda3d76e..00000000000 --- a/src/test/run-pass/numbers-arithmetic/shift-various-types.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/shift.rs b/src/test/run-pass/numbers-arithmetic/shift.rs deleted file mode 100644 index 2fc77928ef1..00000000000 --- a/src/test/run-pass/numbers-arithmetic/shift.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs b/src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs deleted file mode 100644 index 6d0462b460e..00000000000 --- a/src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/u128-as-f32.rs b/src/test/run-pass/numbers-arithmetic/u128-as-f32.rs deleted file mode 100644 index bef7deb6276..00000000000 --- a/src/test/run-pass/numbers-arithmetic/u128-as-f32.rs +++ /dev/null @@ -1,49 +0,0 @@ -// run-pass -// ignore-emscripten u128 not supported - -#![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/src/test/run-pass/numbers-arithmetic/u128.rs b/src/test/run-pass/numbers-arithmetic/u128.rs deleted file mode 100644 index 93940716323..00000000000 --- a/src/test/run-pass/numbers-arithmetic/u128.rs +++ /dev/null @@ -1,121 +0,0 @@ -// run-pass -// ignore-emscripten u128 not supported - - -#![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_value())); - 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_value() - 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/src/test/run-pass/numbers-arithmetic/u32-decr.rs b/src/test/run-pass/numbers-arithmetic/u32-decr.rs deleted file mode 100644 index d9e09781877..00000000000 --- a/src/test/run-pass/numbers-arithmetic/u32-decr.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - - - - -pub fn main() { - let mut word: u32 = 200000; - word = word - 1; - assert_eq!(word, 199999); -} diff --git a/src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs b/src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs deleted file mode 100644 index b16ec011d06..00000000000 --- a/src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/u8-incr.rs b/src/test/run-pass/numbers-arithmetic/u8-incr.rs deleted file mode 100644 index 5242acf5b98..00000000000 --- a/src/test/run-pass/numbers-arithmetic/u8-incr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/numbers-arithmetic/uint.rs b/src/test/run-pass/numbers-arithmetic/uint.rs deleted file mode 100644 index d219eae8f33..00000000000 --- a/src/test/run-pass/numbers-arithmetic/uint.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - - - -// pretty-expanded FIXME #23616 - -pub fn main() { let _x: usize = 10 as usize; } diff --git a/src/test/run-pass/object-lifetime-default-default-to-static.rs b/src/test/run-pass/object-lifetime-default-default-to-static.rs deleted file mode 100644 index 467767ae59d..00000000000 --- a/src/test/run-pass/object-lifetime-default-default-to-static.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/object-lifetime-default-from-rptr-box.rs b/src/test/run-pass/object-lifetime-default-from-rptr-box.rs deleted file mode 100644 index 8ac45b3db71..00000000000 --- a/src/test/run-pass/object-lifetime-default-from-rptr-box.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/object-lifetime-default-from-rptr-mut.rs b/src/test/run-pass/object-lifetime-default-from-rptr-mut.rs deleted file mode 100644 index a09fc03ab9b..00000000000 --- a/src/test/run-pass/object-lifetime-default-from-rptr-mut.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/object-lifetime-default-from-rptr.rs b/src/test/run-pass/object-lifetime-default-from-rptr.rs deleted file mode 100644 index 5093b1c27d0..00000000000 --- a/src/test/run-pass/object-lifetime-default-from-rptr.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/object-method-numbering.rs b/src/test/run-pass/object-method-numbering.rs deleted file mode 100644 index bf80a80f406..00000000000 --- a/src/test/run-pass/object-method-numbering.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// Test for using an object with an associated type binding as the -// instantiation for a generic type with a bound. - - -trait SomeTrait { - type SomeType; - - fn get(&self) -> Self::SomeType; -} - -fn get_int+?Sized>(x: &T) -> i32 { - x.get() -} - -impl SomeTrait for i32 { - type SomeType = i32; - fn get(&self) -> i32 { - *self - } -} - -fn main() { - let x = 22; - let x1: &dyn SomeTrait = &x; - let y = get_int(x1); - assert_eq!(x, y); -} diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/run-pass/objects-coerce-freeze-borrored.rs deleted file mode 100644 index 704d77480b8..00000000000 --- a/src/test/run-pass/objects-coerce-freeze-borrored.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs deleted file mode 100644 index 9b88d8ea7bc..00000000000 --- a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/objects-owned-object-owned-method.rs b/src/test/run-pass/objects-owned-object-owned-method.rs deleted file mode 100644 index 4b7b68f2217..00000000000 --- a/src/test/run-pass/objects-owned-object-owned-method.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/once-move-out-on-heap.rs b/src/test/run-pass/once-move-out-on-heap.rs deleted file mode 100644 index 4e2e400cec0..00000000000 --- a/src/test/run-pass/once-move-out-on-heap.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/one-tuple.rs b/src/test/run-pass/one-tuple.rs deleted file mode 100644 index 00fbadce1ac..00000000000 --- a/src/test/run-pass/one-tuple.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/op-assign-builtins-by-ref.rs b/src/test/run-pass/op-assign-builtins-by-ref.rs deleted file mode 100644 index 96853854d6c..00000000000 --- a/src/test/run-pass/op-assign-builtins-by-ref.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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/src/test/run-pass/opeq.rs b/src/test/run-pass/opeq.rs deleted file mode 100644 index 9737be97fa3..00000000000 --- a/src/test/run-pass/opeq.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/operator-associativity.rs b/src/test/run-pass/operator-associativity.rs deleted file mode 100644 index 4f40c80bc4c..00000000000 --- a/src/test/run-pass/operator-associativity.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -// Testcase for issue #130, operator associativity. - -pub fn main() { assert_eq!(3 * 5 / 2, 7); } diff --git a/src/test/run-pass/operator-multidispatch.rs b/src/test/run-pass/operator-multidispatch.rs deleted file mode 100644 index 0d1dcfd8bdd..00000000000 --- a/src/test/run-pass/operator-multidispatch.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs deleted file mode 100644 index 6b3abcbc76c..00000000000 --- a/src/test/run-pass/operator-overloading.rs +++ /dev/null @@ -1,81 +0,0 @@ -// 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/src/test/run-pass/optimization-fuel-0.rs b/src/test/run-pass/optimization-fuel-0.rs deleted file mode 100644 index f86972b7348..00000000000 --- a/src/test/run-pass/optimization-fuel-0.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - -#![crate_name="foo"] - -use std::mem::size_of; - -// (#55495: The --error-format is to sidestep an issue in our test harness) -// compile-flags: --error-format human -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/src/test/run-pass/optimization-fuel-0.stderr b/src/test/run-pass/optimization-fuel-0.stderr deleted file mode 100644 index 3ad405b2b50..00000000000 --- a/src/test/run-pass/optimization-fuel-0.stderr +++ /dev/null @@ -1 +0,0 @@ -optimization-fuel-exhausted: Reorder fields of "S1" diff --git a/src/test/run-pass/optimization-fuel-1.rs b/src/test/run-pass/optimization-fuel-1.rs deleted file mode 100644 index 98283066361..00000000000 --- a/src/test/run-pass/optimization-fuel-1.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -#![crate_name="foo"] - -use std::mem::size_of; - -// (#55495: The --error-format is to sidestep an issue in our test harness) -// compile-flags: --error-format human -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/src/test/run-pass/optimization-fuel-1.stderr b/src/test/run-pass/optimization-fuel-1.stderr deleted file mode 100644 index 197e45219c3..00000000000 --- a/src/test/run-pass/optimization-fuel-1.stderr +++ /dev/null @@ -1 +0,0 @@ -optimization-fuel-exhausted: Reorder fields of "S2" diff --git a/src/test/run-pass/option-ext.rs b/src/test/run-pass/option-ext.rs deleted file mode 100644 index 76d0cf43984..00000000000 --- a/src/test/run-pass/option-ext.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -pub fn main() { - let thing = "{{ f }}"; - let f = thing.find("{{"); - - if f.is_none() { - println!("None!"); - } -} diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs deleted file mode 100644 index 173f803ee24..00000000000 --- a/src/test/run-pass/option-unwrap.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -use std::cell::Cell; - -struct dtor<'a> { - x: &'a Cell, -} - -impl<'a> Drop for dtor<'a> { - fn drop(&mut self) { - self.x.set(self.x.get() - 1); - } -} - -fn unwrap(o: Option) -> T { - match o { - Some(v) => v, - None => panic!() - } -} - -pub fn main() { - let x = &Cell::new(1); - - { - let b = Some(dtor { x:x }); - let _c = unwrap(b); - } - - assert_eq!(x.get(), 0); -} diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs deleted file mode 100644 index 5e9265be4b9..00000000000 --- a/src/test/run-pass/out-of-stack.rs +++ /dev/null @@ -1,90 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(unconditional_recursion)] -// ignore-android: FIXME (#20004) -// ignore-musl -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes - -#![feature(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 { 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/src/test/run-pass/out-pointer-aliasing.rs b/src/test/run-pass/out-pointer-aliasing.rs deleted file mode 100644 index b28a0910179..00000000000 --- a/src/test/run-pass/out-pointer-aliasing.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/output-slot-variants.rs b/src/test/run-pass/output-slot-variants.rs deleted file mode 100644 index af4caf75669..00000000000 --- a/src/test/run-pass/output-slot-variants.rs +++ /dev/null @@ -1,70 +0,0 @@ -// 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/src/test/run-pass/over-constrained-vregs.rs b/src/test/run-pass/over-constrained-vregs.rs deleted file mode 100644 index cc808147600..00000000000 --- a/src/test/run-pass/over-constrained-vregs.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs b/src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs deleted file mode 100644 index 3d4069f368d..00000000000 --- a/src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -#![feature(overlapping_marker_traits)] -#![feature(specialization)] - -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/src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs b/src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs deleted file mode 100644 index 38331390237..00000000000 --- a/src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs b/src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs deleted file mode 100644 index 112455f91f9..00000000000 --- a/src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs +++ /dev/null @@ -1,30 +0,0 @@ -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/src/test/run-pass/overloaded/overloaded-autoderef-count.rs b/src/test/run-pass/overloaded/overloaded-autoderef-count.rs deleted file mode 100644 index d58deda09f7..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef-count.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs b/src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs deleted file mode 100644 index 1c8c7cca93c..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded/overloaded-autoderef-order.rs deleted file mode 100644 index 1ae16d2a7fc..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef-order.rs +++ /dev/null @@ -1,71 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs deleted file mode 100644 index f8e6d12088f..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs b/src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs deleted file mode 100644 index d065e825cc3..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-autoderef.rs b/src/test/run-pass/overloaded/overloaded-autoderef.rs deleted file mode 100644 index e850633e34f..00000000000 --- a/src/test/run-pass/overloaded/overloaded-autoderef.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs b/src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs deleted file mode 100644 index 1afab9a1ffb..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs b/src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs deleted file mode 100644 index 38087bc8710..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs b/src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs deleted file mode 100644 index 9a7bfaa9bf4..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs deleted file mode 100644 index fde1ad20f7d..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-simple.rs b/src/test/run-pass/overloaded/overloaded-calls-simple.rs deleted file mode 100644 index 41318360799..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-simple.rs +++ /dev/null @@ -1,78 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-calls-zero-args.rs b/src/test/run-pass/overloaded/overloaded-calls-zero-args.rs deleted file mode 100644 index 69ca88619b8..00000000000 --- a/src/test/run-pass/overloaded/overloaded-calls-zero-args.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-deref-count.rs b/src/test/run-pass/overloaded/overloaded-deref-count.rs deleted file mode 100644 index e2f1e10b5c8..00000000000 --- a/src/test/run-pass/overloaded/overloaded-deref-count.rs +++ /dev/null @@ -1,78 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-deref.rs b/src/test/run-pass/overloaded/overloaded-deref.rs deleted file mode 100644 index 73d8232a322..00000000000 --- a/src/test/run-pass/overloaded/overloaded-deref.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-index-assoc-list.rs b/src/test/run-pass/overloaded/overloaded-index-assoc-list.rs deleted file mode 100644 index eb027afeacd..00000000000 --- a/src/test/run-pass/overloaded/overloaded-index-assoc-list.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-index-autoderef.rs b/src/test/run-pass/overloaded/overloaded-index-autoderef.rs deleted file mode 100644 index 6996ee32933..00000000000 --- a/src/test/run-pass/overloaded/overloaded-index-autoderef.rs +++ /dev/null @@ -1,77 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-index-in-field.rs b/src/test/run-pass/overloaded/overloaded-index-in-field.rs deleted file mode 100644 index 8a1fa7deb99..00000000000 --- a/src/test/run-pass/overloaded/overloaded-index-in-field.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded-index.rs b/src/test/run-pass/overloaded/overloaded-index.rs deleted file mode 100644 index 5ad6d2e7004..00000000000 --- a/src/test/run-pass/overloaded/overloaded-index.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs b/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs deleted file mode 100644 index c87ba6a023b..00000000000 --- a/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs b/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs deleted file mode 100644 index 61edd2ace3a..00000000000 --- a/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/owned-implies-static.rs b/src/test/run-pass/owned-implies-static.rs deleted file mode 100644 index 2efa8cc02f4..00000000000 --- a/src/test/run-pass/owned-implies-static.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn f(_x: T) {} - -pub fn main() { - f(Box::new(5)); -} diff --git a/src/test/run-pass/packed/auxiliary/packed.rs b/src/test/run-pass/packed/auxiliary/packed.rs deleted file mode 100644 index cba166facf4..00000000000 --- a/src/test/run-pass/packed/auxiliary/packed.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[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/src/test/run-pass/packed/packed-struct-borrow-element.rs b/src/test/run-pass/packed/packed-struct-borrow-element.rs deleted file mode 100644 index 6ac42ed0d47..00000000000 --- a/src/test/run-pass/packed/packed-struct-borrow-element.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -#![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/src/test/run-pass/packed/packed-struct-drop-aligned.rs b/src/test/run-pass/packed/packed-struct-drop-aligned.rs deleted file mode 100644 index fab3bbedac6..00000000000 --- a/src/test/run-pass/packed/packed-struct-drop-aligned.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-generic-layout.rs b/src/test/run-pass/packed/packed-struct-generic-layout.rs deleted file mode 100644 index e064eede4ce..00000000000 --- a/src/test/run-pass/packed/packed-struct-generic-layout.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-generic-size.rs b/src/test/run-pass/packed/packed-struct-generic-size.rs deleted file mode 100644 index 7c93e46c30c..00000000000 --- a/src/test/run-pass/packed/packed-struct-generic-size.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-layout.rs b/src/test/run-pass/packed/packed-struct-layout.rs deleted file mode 100644 index d49c222e648..00000000000 --- a/src/test/run-pass/packed/packed-struct-layout.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-match.rs b/src/test/run-pass/packed/packed-struct-match.rs deleted file mode 100644 index 9a572ced717..00000000000 --- a/src/test/run-pass/packed/packed-struct-match.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-optimized-enum.rs b/src/test/run-pass/packed/packed-struct-optimized-enum.rs deleted file mode 100644 index 7ce62464ef0..00000000000 --- a/src/test/run-pass/packed/packed-struct-optimized-enum.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-size-xc.rs b/src/test/run-pass/packed/packed-struct-size-xc.rs deleted file mode 100644 index 46112d51d83..00000000000 --- a/src/test/run-pass/packed/packed-struct-size-xc.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-size.rs b/src/test/run-pass/packed/packed-struct-size.rs deleted file mode 100644 index c832c7cfad5..00000000000 --- a/src/test/run-pass/packed/packed-struct-size.rs +++ /dev/null @@ -1,157 +0,0 @@ -// 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/src/test/run-pass/packed/packed-struct-vec.rs b/src/test/run-pass/packed/packed-struct-vec.rs deleted file mode 100644 index 18676cfc22e..00000000000 --- a/src/test/run-pass/packed/packed-struct-vec.rs +++ /dev/null @@ -1,120 +0,0 @@ -// 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/src/test/run-pass/packed/packed-tuple-struct-layout.rs b/src/test/run-pass/packed/packed-tuple-struct-layout.rs deleted file mode 100644 index b88637fbe56..00000000000 --- a/src/test/run-pass/packed/packed-tuple-struct-layout.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/packed/packed-tuple-struct-size.rs b/src/test/run-pass/packed/packed-tuple-struct-size.rs deleted file mode 100644 index f7a3c903fca..00000000000 --- a/src/test/run-pass/packed/packed-tuple-struct-size.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs b/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs deleted file mode 100644 index 659864c1d9b..00000000000 --- a/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs b/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs deleted file mode 100644 index 9c099911eab..00000000000 --- a/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/panic-runtime/abort.rs b/src/test/run-pass/panic-runtime/abort.rs deleted file mode 100644 index f625fe35d72..00000000000 --- a/src/test/run-pass/panic-runtime/abort.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs b/src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs deleted file mode 100644 index c0e05740542..00000000000 --- a/src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/panic-runtime/link-to-abort.rs b/src/test/run-pass/panic-runtime/link-to-abort.rs deleted file mode 100644 index 422206c574d..00000000000 --- a/src/test/run-pass/panic-runtime/link-to-abort.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -// compile-flags:-C panic=abort -// no-prefer-dynamic -// ignore-macos - -#![feature(panic_abort)] - -extern crate panic_abort; - -fn main() {} diff --git a/src/test/run-pass/panic-runtime/link-to-unwind.rs b/src/test/run-pass/panic-runtime/link-to-unwind.rs deleted file mode 100644 index 59036ca99bd..00000000000 --- a/src/test/run-pass/panic-runtime/link-to-unwind.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -// no-prefer-dynamic - -#![feature(panic_unwind)] - -extern crate panic_unwind; - -fn main() { -} diff --git a/src/test/run-pass/panic-runtime/lto-abort.rs b/src/test/run-pass/panic-runtime/lto-abort.rs deleted file mode 100644 index 8fff71a629a..00000000000 --- a/src/test/run-pass/panic-runtime/lto-abort.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/panic-runtime/lto-unwind.rs b/src/test/run-pass/panic-runtime/lto-unwind.rs deleted file mode 100644 index 94a0b596e4a..00000000000 --- a/src/test/run-pass/panic-runtime/lto-unwind.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/panic-uninitialized-zeroed.rs b/src/test/run-pass/panic-uninitialized-zeroed.rs deleted file mode 100644 index 0c97babd51c..00000000000 --- a/src/test/run-pass/panic-uninitialized-zeroed.rs +++ /dev/null @@ -1,102 +0,0 @@ -// run-pass -// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding -// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results -// in a runtime panic. - -#![feature(never_type)] -#![allow(deprecated)] - -use std::{mem, panic}; - -#[allow(dead_code)] -struct Foo { - x: u8, - y: !, -} - -enum Bar {} - -fn main() { - unsafe { - assert_eq!( - panic::catch_unwind(|| { - mem::uninitialized::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type !" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::zeroed::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type !" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::MaybeUninit::::uninit().assume_init() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type !" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::uninitialized::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Foo" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::zeroed::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Foo" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::MaybeUninit::::uninit().assume_init() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Foo" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::uninitialized::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Bar" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::zeroed::() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Bar" - })), - Some(true) - ); - - assert_eq!( - panic::catch_unwind(|| { - mem::MaybeUninit::::uninit().assume_init() - }).err().and_then(|a| a.downcast_ref::().map(|s| { - s == "Attempted to instantiate uninhabited type Bar" - })), - Some(true) - ); - } -} diff --git a/src/test/run-pass/panics/panic-handler-chain.rs b/src/test/run-pass/panics/panic-handler-chain.rs deleted file mode 100644 index 93044b5cb25..00000000000 --- a/src/test/run-pass/panics/panic-handler-chain.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/panics/panic-handler-flail-wildly.rs b/src/test/run-pass/panics/panic-handler-flail-wildly.rs deleted file mode 100644 index 6badd203842..00000000000 --- a/src/test/run-pass/panics/panic-handler-flail-wildly.rs +++ /dev/null @@ -1,55 +0,0 @@ -// 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/src/test/run-pass/panics/panic-handler-set-twice.rs b/src/test/run-pass/panics/panic-handler-set-twice.rs deleted file mode 100644 index 0312ed221ca..00000000000 --- a/src/test/run-pass/panics/panic-handler-set-twice.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/panics/panic-in-dtor-drops-fields.rs b/src/test/run-pass/panics/panic-in-dtor-drops-fields.rs deleted file mode 100644 index caddd942dc0..00000000000 --- a/src/test/run-pass/panics/panic-in-dtor-drops-fields.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/panics/panic-recover-propagate.rs b/src/test/run-pass/panics/panic-recover-propagate.rs deleted file mode 100644 index 7969336ca74..00000000000 --- a/src/test/run-pass/panics/panic-recover-propagate.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/panics/panic-safe.rs b/src/test/run-pass/panics/panic-safe.rs deleted file mode 100644 index 9867cc56406..00000000000 --- a/src/test/run-pass/panics/panic-safe.rs +++ /dev/null @@ -1,51 +0,0 @@ -// run-pass -#![allow(dead_code)] - -use std::panic::{UnwindSafe, AssertUnwindSafe}; -use std::cell::RefCell; -use std::sync::{Mutex, RwLock, Arc}; -use std::rc::Rc; - -struct Foo { a: i32 } - -fn assert() {} - -fn main() { - assert::(); - assert::<&i32>(); - assert::<*mut i32>(); - assert::<*const i32>(); - assert::(); - assert::(); - assert::<&str>(); - assert::(); - assert::<&Foo>(); - assert::>(); - assert::(); - assert::>(); - assert::>(); - assert::>(); - assert::>(); - assert::<&Mutex>(); - assert::<&RwLock>(); - assert::>(); - assert::>(); - assert::>(); - - trait Trait: UnwindSafe {} - assert::>(); - - fn bar() { - assert::>(); - assert::>(); - } - fn baz() { - assert::>(); - assert::>(); - assert::>(); - assert::>(); - assert::<&AssertUnwindSafe>(); - assert::>>(); - assert::>>(); - } -} diff --git a/src/test/run-pass/paren-free.rs b/src/test/run-pass/paren-free.rs deleted file mode 100644 index 8e8bb8800ec..00000000000 --- a/src/test/run-pass/paren-free.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/parse-assoc-type-lt.rs b/src/test/run-pass/parse-assoc-type-lt.rs deleted file mode 100644 index d3fe6079a5d..00000000000 --- a/src/test/run-pass/parse-assoc-type-lt.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -trait Foo { - type T; - fn foo() -> Box<::T>; -} - -fn main() {} diff --git a/src/test/run-pass/parse-panic.rs b/src/test/run-pass/parse-panic.rs deleted file mode 100644 index aeb2ba4faa5..00000000000 --- a/src/test/run-pass/parse-panic.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![allow(unreachable_code)] - -fn dont_call_me() { panic!(); println!("{}", 1); } - -pub fn main() { } diff --git a/src/test/run-pass/parser-unicode-whitespace.rs b/src/test/run-pass/parser-unicode-whitespace.rs deleted file mode 100644 index 2d1fa7dc42e..00000000000 --- a/src/test/run-pass/parser-unicode-whitespace.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/path.rs b/src/test/run-pass/path.rs deleted file mode 100644 index 4c137de82d0..00000000000 --- a/src/test/run-pass/path.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -mod foo { - pub fn bar(_offset: usize) { } -} - -pub fn main() { foo::bar(0); } diff --git a/src/test/run-pass/paths-containing-nul.rs b/src/test/run-pass/paths-containing-nul.rs deleted file mode 100644 index c9bf710b8e7..00000000000 --- a/src/test/run-pass/paths-containing-nul.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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(|_| ())) -} - -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/src/test/run-pass/print-stdout-eprint-stderr.rs b/src/test/run-pass/print-stdout-eprint-stderr.rs deleted file mode 100644 index 70c083e0800..00000000000 --- a/src/test/run-pass/print-stdout-eprint-stderr.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs b/src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs deleted file mode 100644 index 8ccbd3f12bf..00000000000 --- a/src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub trait A { - fn frob(&self); -} - -impl A for isize { fn frob(&self) {} } - -pub fn frob(t: T) { - t.frob(); -} diff --git a/src/test/run-pass/privacy/auxiliary/privacy_reexport.rs b/src/test/run-pass/privacy/auxiliary/privacy_reexport.rs deleted file mode 100644 index 6b72dbc9233..00000000000 --- a/src/test/run-pass/privacy/auxiliary/privacy_reexport.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub extern crate core; -pub use foo as bar; - -pub mod foo { - pub fn frob() {} -} diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs b/src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs deleted file mode 100644 index 74d3504d5be..00000000000 --- a/src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod a { - pub use a::b::c; - - pub mod b { - pub mod c { - fn f(){} - fn g(){} - } - } -} diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs b/src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs deleted file mode 100644 index 772c9627a71..00000000000 --- a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub struct Foo { - pub name: isize -} diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs b/src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs deleted file mode 100644 index 20d7066d36d..00000000000 --- a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate pub_use_xcrate1; - -pub use pub_use_xcrate1::Foo; diff --git a/src/test/run-pass/privacy/priv-impl-prim-ty.rs b/src/test/run-pass/privacy/priv-impl-prim-ty.rs deleted file mode 100644 index 5d6a6b64ed3..00000000000 --- a/src/test/run-pass/privacy/priv-impl-prim-ty.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/privacy/privacy-ns.rs b/src/test/run-pass/privacy/privacy-ns.rs deleted file mode 100644 index c32e3f17880..00000000000 --- a/src/test/run-pass/privacy/privacy-ns.rs +++ /dev/null @@ -1,114 +0,0 @@ -// 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/src/test/run-pass/privacy/privacy-reexport.rs b/src/test/run-pass/privacy/privacy-reexport.rs deleted file mode 100644 index b3ec3af04ac..00000000000 --- a/src/test/run-pass/privacy/privacy-reexport.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/privacy/private-class-field.rs b/src/test/run-pass/privacy/private-class-field.rs deleted file mode 100644 index 98e32ee0745..00000000000 --- a/src/test/run-pass/privacy/private-class-field.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/privacy/pub-extern-privacy.rs b/src/test/run-pass/privacy/pub-extern-privacy.rs deleted file mode 100644 index 832acfbadcb..00000000000 --- a/src/test/run-pass/privacy/pub-extern-privacy.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/privacy/pub-use-xcrate.rs b/src/test/run-pass/privacy/pub-use-xcrate.rs deleted file mode 100644 index e8a6e8cf182..00000000000 --- a/src/test/run-pass/privacy/pub-use-xcrate.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs b/src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs deleted file mode 100644 index f163619e7cb..00000000000 --- a/src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/proc-macro/add-impl.rs b/src/test/run-pass/proc-macro/add-impl.rs deleted file mode 100644 index ff2897a5e86..00000000000 --- a/src/test/run-pass/proc-macro/add-impl.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/proc-macro/append-impl.rs b/src/test/run-pass/proc-macro/append-impl.rs deleted file mode 100644 index a4938401348..00000000000 --- a/src/test/run-pass/proc-macro/append-impl.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/proc-macro/attr-args.rs b/src/test/run-pass/proc-macro/attr-args.rs deleted file mode 100644 index 764f507abfc..00000000000 --- a/src/test/run-pass/proc-macro/attr-args.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/proc-macro/attr-cfg.rs b/src/test/run-pass/proc-macro/attr-cfg.rs deleted file mode 100644 index 2aed9e2e814..00000000000 --- a/src/test/run-pass/proc-macro/attr-cfg.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/proc-macro/attr-on-trait.rs b/src/test/run-pass/proc-macro/attr-on-trait.rs deleted file mode 100644 index e0edee630a4..00000000000 --- a/src/test/run-pass/proc-macro/attr-on-trait.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass/proc-macro/auxiliary/add-impl.rs deleted file mode 100644 index 741e64875b6..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/add-impl.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass/proc-macro/auxiliary/append-impl.rs deleted file mode 100644 index b032b133759..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/append-impl.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/attr-args.rs b/src/test/run-pass/proc-macro/auxiliary/attr-args.rs deleted file mode 100644 index 8dd2a5ac786..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/attr-args.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs deleted file mode 100644 index f50e18d7be3..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs b/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs deleted file mode 100644 index d89aaac59f6..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs b/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs deleted file mode 100644 index ff000228218..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/call-site.rs b/src/test/run-pass/proc-macro/auxiliary/call-site.rs deleted file mode 100644 index e64a5a3438a..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/call-site.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs b/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs deleted file mode 100644 index e09622e48bf..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs +++ /dev/null @@ -1,32 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![feature(proc_macro_hygiene, 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/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs deleted file mode 100644 index 41f73f5963a..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass/proc-macro/auxiliary/derive-a.rs deleted file mode 100644 index cd2be5fd84d..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-a.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs b/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs deleted file mode 100644 index e78e5bb8f4c..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs deleted file mode 100644 index e7e9634e0bd..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-b.rs b/src/test/run-pass/proc-macro/auxiliary/derive-b.rs deleted file mode 100644 index 3e6af67a9f4..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-b.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs deleted file mode 100644 index dbf44ed1b05..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs b/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs deleted file mode 100644 index b6d1e133af7..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs deleted file mode 100644 index ce7a50d2381..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs b/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs deleted file mode 100644 index a6f0eec126a..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/derive-union.rs b/src/test/run-pass/proc-macro/auxiliary/derive-union.rs deleted file mode 100644 index d950e1e773c..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/derive-union.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/double.rs b/src/test/run-pass/proc-macro/auxiliary/double.rs deleted file mode 100644 index 3a2e8d04c36..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/double.rs +++ /dev/null @@ -1,15 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -// 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 { - format!("mod foo {{ {} }}", input.to_string()).parse().unwrap() -} diff --git a/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs b/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs deleted file mode 100644 index 1cf7534b289..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs +++ /dev/null @@ -1,5 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![deny(unused_variables)] diff --git a/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs deleted file mode 100644 index 5155a4b8558..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs b/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs deleted file mode 100644 index 4319e921225..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs +++ /dev/null @@ -1,40 +0,0 @@ -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/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs deleted file mode 100644 index d1a1c584f8b..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs deleted file mode 100644 index f7e7e0b5751..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs +++ /dev/null @@ -1,7 +0,0 @@ -extern crate hygiene_example_codegen; - -pub use hygiene_example_codegen::hello; - -pub fn print(string: &str) { - println!("{}", string); -} diff --git a/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs deleted file mode 100644 index 5e50a6e916f..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs +++ /dev/null @@ -1,27 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![feature(proc_macro_quote, proc_macro_hygiene)] -#![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/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs b/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs deleted file mode 100644 index e7af66da797..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs b/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs deleted file mode 100644 index dae05204b8b..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs b/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs deleted file mode 100644 index f5fe8cabbce..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs b/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs deleted file mode 100644 index cc582c1522c..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/negative-token.rs b/src/test/run-pass/proc-macro/auxiliary/negative-token.rs deleted file mode 100644 index 8b89f2e3731..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/negative-token.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/not-joint.rs b/src/test/run-pass/proc-macro/auxiliary/not-joint.rs deleted file mode 100644 index e6c09f7628e..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/not-joint.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs b/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs deleted file mode 100644 index ad1e770a4dc..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs b/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs deleted file mode 100644 index 9a78f0a8955..00000000000 --- a/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[macro_export] -macro_rules! reemit_legacy { - ($($tok:tt)*) => ($($tok)*) -} - -#[macro_export] -macro_rules! say_hello_extern { - ($macname:ident) => ( $macname! { "Hello, world!" }) -} diff --git a/src/test/run-pass/proc-macro/bang-macro.rs b/src/test/run-pass/proc-macro/bang-macro.rs deleted file mode 100644 index 7073c71538c..00000000000 --- a/src/test/run-pass/proc-macro/bang-macro.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// aux-build:bang-macro.rs - -#![feature(proc_macro_hygiene)] - -extern crate bang_macro; -use bang_macro::rewrite; - -fn main() { - assert_eq!(rewrite!("Hello, world!"), "NOT Hello, world!"); -} diff --git a/src/test/run-pass/proc-macro/call-site.rs b/src/test/run-pass/proc-macro/call-site.rs deleted file mode 100644 index 096d0ec533a..00000000000 --- a/src/test/run-pass/proc-macro/call-site.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - -#![allow(unused_variables)] -#![allow(unused_imports)] -// aux-build:call-site.rs - -#![feature(proc_macro_hygiene)] - -extern crate call_site; -use call_site::*; - -fn main() { - let x1 = 10; - call_site::check!(let x2 = x1;); - let x6 = x5; -} diff --git a/src/test/run-pass/proc-macro/count_compound_ops.rs b/src/test/run-pass/proc-macro/count_compound_ops.rs deleted file mode 100644 index 966ab616cdf..00000000000 --- a/src/test/run-pass/proc-macro/count_compound_ops.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// aux-build:count_compound_ops.rs - -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs b/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs deleted file mode 100644 index 2cd5b487301..00000000000 --- a/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/proc-macro/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/derive-attr-cfg.rs deleted file mode 100644 index 3947746286d..00000000000 --- a/src/test/run-pass/proc-macro/derive-attr-cfg.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/proc-macro/derive-b.rs b/src/test/run-pass/proc-macro/derive-b.rs deleted file mode 100644 index 41291a87b01..00000000000 --- a/src/test/run-pass/proc-macro/derive-b.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// aux-build:derive-b.rs - -extern crate 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/src/test/run-pass/proc-macro/derive-same-struct.rs b/src/test/run-pass/proc-macro/derive-same-struct.rs deleted file mode 100644 index 528b0f22a81..00000000000 --- a/src/test/run-pass/proc-macro/derive-same-struct.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/derive-same-struct.stdout b/src/test/run-pass/proc-macro/derive-same-struct.stdout deleted file mode 100644 index 77605de5e33..00000000000 --- a/src/test/run-pass/proc-macro/derive-same-struct.stdout +++ /dev/null @@ -1 +0,0 @@ -input1: "struct A;" diff --git a/src/test/run-pass/proc-macro/derive-test.rs b/src/test/run-pass/proc-macro/derive-test.rs deleted file mode 100644 index b81e38432e8..00000000000 --- a/src/test/run-pass/proc-macro/derive-test.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/proc-macro/derive-two-attrs.rs b/src/test/run-pass/proc-macro/derive-two-attrs.rs deleted file mode 100644 index 08225b8e3f2..00000000000 --- a/src/test/run-pass/proc-macro/derive-two-attrs.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/proc-macro/derive-union.rs b/src/test/run-pass/proc-macro/derive-union.rs deleted file mode 100644 index e83eee0936a..00000000000 --- a/src/test/run-pass/proc-macro/derive-union.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/proc-macro/empty-crate.rs b/src/test/run-pass/proc-macro/empty-crate.rs deleted file mode 100644 index 3e54c9feebc..00000000000 --- a/src/test/run-pass/proc-macro/empty-crate.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -#![allow(unused_imports)] -// aux-build:empty-crate.rs - -#[macro_use] -extern crate empty_crate; - -fn main() {} diff --git a/src/test/run-pass/proc-macro/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/expand-with-a-macro.rs deleted file mode 100644 index 418178d0f0e..00000000000 --- a/src/test/run-pass/proc-macro/expand-with-a-macro.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/proc-macro/gen-lifetime-token.rs b/src/test/run-pass/proc-macro/gen-lifetime-token.rs deleted file mode 100644 index 588bd2b76c1..00000000000 --- a/src/test/run-pass/proc-macro/gen-lifetime-token.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/proc-macro/hygiene_example.rs b/src/test/run-pass/proc-macro/hygiene_example.rs deleted file mode 100644 index 56ea9daacc3..00000000000 --- a/src/test/run-pass/proc-macro/hygiene_example.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass - -#![allow(unused_macros)] -// aux-build:hygiene_example_codegen.rs -// aux-build:hygiene_example.rs - -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/proc-macro/issue-39889.rs b/src/test/run-pass/proc-macro/issue-39889.rs deleted file mode 100644 index ada125a215a..00000000000 --- a/src/test/run-pass/proc-macro/issue-39889.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/proc-macro/issue-42708.rs b/src/test/run-pass/proc-macro/issue-42708.rs deleted file mode 100644 index e8f445aaaf7..00000000000 --- a/src/test/run-pass/proc-macro/issue-42708.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/proc-macro/issue-50061.rs b/src/test/run-pass/proc-macro/issue-50061.rs deleted file mode 100644 index 01c6b80b46c..00000000000 --- a/src/test/run-pass/proc-macro/issue-50061.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/proc-macro/load-two.rs b/src/test/run-pass/proc-macro/load-two.rs deleted file mode 100644 index 5ce0e65452e..00000000000 --- a/src/test/run-pass/proc-macro/load-two.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/proc-macro/modify-ast.rs b/src/test/run-pass/proc-macro/modify-ast.rs deleted file mode 100644 index ea9bf837c24..00000000000 --- a/src/test/run-pass/proc-macro/modify-ast.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/proc-macro/negative-token.rs b/src/test/run-pass/proc-macro/negative-token.rs deleted file mode 100644 index 3d018fe60a1..00000000000 --- a/src/test/run-pass/proc-macro/negative-token.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// aux-build:negative-token.rs - -#![feature(proc_macro_hygiene)] - -extern crate negative_token; - -use negative_token::*; - -fn main() { - assert_eq!(-1, neg_one!()); - assert_eq!(-1.0, neg_one_float!()); -} diff --git a/src/test/run-pass/proc-macro/not-joint.rs b/src/test/run-pass/proc-macro/not-joint.rs deleted file mode 100644 index 30da2811ed4..00000000000 --- a/src/test/run-pass/proc-macro/not-joint.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/proc-macro/smoke.rs b/src/test/run-pass/proc-macro/smoke.rs deleted file mode 100644 index 04625559b91..00000000000 --- a/src/test/run-pass/proc-macro/smoke.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/proc-macro/span-api-tests.rs b/src/test/run-pass/proc-macro/span-api-tests.rs deleted file mode 100644 index 3667e14c9e0..00000000000 --- a/src/test/run-pass/proc-macro/span-api-tests.rs +++ /dev/null @@ -1,62 +0,0 @@ -// run-pass -// aux-build:span-api-tests.rs -// aux-build:span-test-macros.rs - -// ignore-pretty - -#![feature(proc_macro_hygiene)] - -#[macro_use] -extern crate span_test_macros; - -extern crate span_api_tests; - -use span_api_tests::{reemit, assert_fake_source_file, 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_fake_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/src/test/run-pass/proc-macro/struct-field-macro.rs b/src/test/run-pass/proc-macro/struct-field-macro.rs deleted file mode 100644 index 460f4d9f726..00000000000 --- a/src/test/run-pass/proc-macro/struct-field-macro.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/proc_macro.rs b/src/test/run-pass/proc_macro.rs deleted file mode 100644 index 7ff94649003..00000000000 --- a/src/test/run-pass/proc_macro.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass -// aux-build:proc_macro_def.rs -// ignore-cross-compile - -#![feature(proc_macro_hygiene)] - -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/src/test/run-pass/process/process-envs.rs b/src/test/run-pass/process/process-envs.rs deleted file mode 100644 index a7779c55f1f..00000000000 --- a/src/test/run-pass/process/process-envs.rs +++ /dev/null @@ -1,53 +0,0 @@ -// run-pass -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes - -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/src/test/run-pass/process/process-exit.rs b/src/test/run-pass/process/process-exit.rs deleted file mode 100644 index da3b4ca85c2..00000000000 --- a/src/test/run-pass/process/process-exit.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/process/process-remove-from-env.rs b/src/test/run-pass/process/process-remove-from-env.rs deleted file mode 100644 index 32cbb6ac85a..00000000000 --- a/src/test/run-pass/process/process-remove-from-env.rs +++ /dev/null @@ -1,47 +0,0 @@ -// run-pass -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes - -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/src/test/run-pass/process/process-sigpipe.rs b/src/test/run-pass/process/process-sigpipe.rs deleted file mode 100644 index bf589096006..00000000000 --- a/src/test/run-pass/process/process-sigpipe.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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 - -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/src/test/run-pass/process/process-spawn-nonexistent.rs b/src/test/run-pass/process/process-spawn-nonexistent.rs deleted file mode 100644 index 182cf1748fe..00000000000 --- a/src/test/run-pass/process/process-spawn-nonexistent.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/process/process-spawn-with-unicode-params.rs b/src/test/run-pass/process/process-spawn-with-unicode-params.rs deleted file mode 100644 index edd3cb26ec3..00000000000 --- a/src/test/run-pass/process/process-spawn-with-unicode-params.rs +++ /dev/null @@ -1,77 +0,0 @@ -// 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/src/test/run-pass/process/process-status-inherits-stdin.rs b/src/test/run-pass/process/process-status-inherits-stdin.rs deleted file mode 100644 index f9b2da7e401..00000000000 --- a/src/test/run-pass/process/process-status-inherits-stdin.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/project-cache-issue-31849.rs b/src/test/run-pass/project-cache-issue-31849.rs deleted file mode 100644 index 07fb6abaeac..00000000000 --- a/src/test/run-pass/project-cache-issue-31849.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/project-cache-issue-37154.rs b/src/test/run-pass/project-cache-issue-37154.rs deleted file mode 100644 index b10239c22d1..00000000000 --- a/src/test/run-pass/project-cache-issue-37154.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/project-defer-unification.rs b/src/test/run-pass/project-defer-unification.rs deleted file mode 100644 index 547ff45c229..00000000000 --- a/src/test/run-pass/project-defer-unification.rs +++ /dev/null @@ -1,104 +0,0 @@ -// run-pass - -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unreachable_code)] -// A regression test extracted from image-0.3.11. The point of -// failure was in `index_colors` below. - -use std::ops::{Deref, DerefMut}; - -#[derive(Copy, Clone)] -pub struct Luma { pub data: [T; 1] } - -impl Pixel for Luma { - type Subpixel = T; -} - -pub struct ImageBuffer { - pixels: P, - c: Container, -} - -pub trait GenericImage: Sized { - type Pixel: Pixel; -} - -pub trait Pixel: Copy + Clone { - type Subpixel: Primitive; -} - -pub trait Primitive: Copy + PartialOrd + Clone { -} - -impl GenericImage for ImageBuffer -where P: Pixel + 'static, - Container: Deref + DerefMut, - P::Subpixel: 'static { - - type Pixel = P; -} - -impl Primitive for u8 { } - -impl ImageBuffer -where P: Pixel + 'static, - P::Subpixel: 'static, - Container: Deref -{ - pub fn pixels<'a>(&'a self) -> Pixels<'a, Self> { - loop { } - } - - pub fn pixels_mut(&mut self) -> PixelsMut

{ - loop { } - } -} - -pub struct Pixels<'a, I: 'a> { - image: &'a I, - x: u32, - y: u32, - width: u32, - height: u32 -} - -impl<'a, I: GenericImage> Iterator for Pixels<'a, I> { - type Item = (u32, u32, I::Pixel); - - fn next(&mut self) -> Option<(u32, u32, I::Pixel)> { - loop { } - } -} - -pub struct PixelsMut<'a, P: Pixel + 'a> where P::Subpixel: 'a { - chunks: &'a mut P::Subpixel -} - -impl<'a, P: Pixel + 'a> Iterator for PixelsMut<'a, P> where P::Subpixel: 'a { - type Item = &'a mut P; - - fn next(&mut self) -> Option<&'a mut P> { - loop { } - } -} - -pub fn index_colors(image: &ImageBuffer>) - -> ImageBuffer, Vec> -where Pix: Pixel + 'static, -{ - // When NLL-enabled, `let mut` below is deemed unnecessary (due to - // the remaining code being unreachable); so ignore that lint. - #![allow(unused_mut)] - - let mut indices: ImageBuffer<_,Vec<_>> = loop { }; - for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) { - // failured occurred here ^^ because we were requiring that we - // could project Pixel or Subpixel from `T_indices` (type of - // `indices`), but the type is insufficiently constrained - // until we reach the return below. - } - indices -} - -fn main() { } diff --git a/src/test/run-pass/pure-sum.rs b/src/test/run-pass/pure-sum.rs deleted file mode 100644 index 2ff6f935a03..00000000000 --- a/src/test/run-pass/pure-sum.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/purity-infer.rs b/src/test/run-pass/purity-infer.rs deleted file mode 100644 index dc0eb89bfa2..00000000000 --- a/src/test/run-pass/purity-infer.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -fn something(f: F) where F: FnOnce() { f(); } -pub fn main() { - something(|| println!("hi!") ); -} diff --git a/src/test/run-pass/range-type-infer.rs b/src/test/run-pass/range-type-infer.rs deleted file mode 100644 index f07c041717f..00000000000 --- a/src/test/run-pass/range-type-infer.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/range.rs b/src/test/run-pass/range.rs deleted file mode 100644 index 82983e37ea1..00000000000 --- a/src/test/run-pass/range.rs +++ /dev/null @@ -1,51 +0,0 @@ -// run-pass - -#![allow(unused_comparisons)] -#![allow(dead_code)] -#![allow(unused_mut)] -// Test range syntax. - - -fn foo() -> isize { 42 } - -// Test that range syntax works in return statements -fn return_range_to() -> ::std::ops::RangeTo { return ..1; } -fn return_full_range() -> ::std::ops::RangeFull { return ..; } - -pub fn main() { - let mut count = 0; - for i in 0_usize..10 { - assert!(i >= 0 && i < 10); - count += i; - } - assert_eq!(count, 45); - - let mut count = 0; - let mut range = 0_usize..10; - for i in range { - assert!(i >= 0 && i < 10); - count += i; - } - assert_eq!(count, 45); - - let mut count = 0; - let mut rf = 3_usize..; - for i in rf.take(10) { - assert!(i >= 3 && i < 13); - count += i; - } - assert_eq!(count, 75); - - 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; - } -} diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs deleted file mode 100644 index 68d9bf7d26b..00000000000 --- a/src/test/run-pass/range_inclusive.rs +++ /dev/null @@ -1,122 +0,0 @@ -// run-pass -// Test inclusive range syntax. - -#![feature(range_is_empty)] -#![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/src/test/run-pass/range_inclusive_gate.rs b/src/test/run-pass/range_inclusive_gate.rs deleted file mode 100644 index e26e31b44a0..00000000000 --- a/src/test/run-pass/range_inclusive_gate.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/ranges-precedence.rs b/src/test/run-pass/ranges-precedence.rs deleted file mode 100644 index db241ed0ccd..00000000000 --- a/src/test/run-pass/ranges-precedence.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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/src/test/run-pass/raw-fat-ptr.rs b/src/test/run-pass/raw-fat-ptr.rs deleted file mode 100644 index 9f50659ed60..00000000000 --- a/src/test/run-pass/raw-fat-ptr.rs +++ /dev/null @@ -1,118 +0,0 @@ -// 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/src/test/run-pass/raw-str.rs b/src/test/run-pass/raw-str.rs deleted file mode 100644 index 0916dddbb7b..00000000000 Binary files a/src/test/run-pass/raw-str.rs and /dev/null differ diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs deleted file mode 100644 index 37113bc0a05..00000000000 --- a/src/test/run-pass/rcvr-borrowed-to-region.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![feature(box_syntax)] - -trait get { - fn get(self) -> 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/src/test/run-pass/reachable-unnameable-items.rs b/src/test/run-pass/reachable-unnameable-items.rs deleted file mode 100644 index f1e53a0d8b4..00000000000 --- a/src/test/run-pass/reachable-unnameable-items.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/reachable-unnameable-type-alias.rs b/src/test/run-pass/reachable-unnameable-type-alias.rs deleted file mode 100644 index 461355f87cf..00000000000 --- a/src/test/run-pass/reachable-unnameable-type-alias.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/readalias.rs b/src/test/run-pass/readalias.rs deleted file mode 100644 index a6bf61803cf..00000000000 --- a/src/test/run-pass/readalias.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs deleted file mode 100644 index 69292d241c3..00000000000 --- a/src/test/run-pass/realloc-16687.rs +++ /dev/null @@ -1,183 +0,0 @@ -// 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)] - -use std::alloc::{Global, Alloc, Layout, handle_alloc_error}; -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 ret = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); - - if PRINT { - println!("allocate({:?}) = {:?}", layout, ret); - } - - ret.cast().as_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 ret = Global.realloc(NonNull::new_unchecked(ptr), old, new.size()) - .unwrap_or_else(|_| handle_alloc_error( - Layout::from_size_align_unchecked(new.size(), old.align()) - )); - - if PRINT { - println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", - ptr, old, new, ret); - } - ret.cast().as_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/src/test/run-pass/reexport-should-still-link.rs b/src/test/run-pass/reexport-should-still-link.rs deleted file mode 100644 index 913da56a184..00000000000 --- a/src/test/run-pass/reexport-should-still-link.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/reexport-star.rs b/src/test/run-pass/reexport-star.rs deleted file mode 100644 index 639ab1a0f3a..00000000000 --- a/src/test/run-pass/reexport-star.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/reexport-test-harness-main.rs b/src/test/run-pass/reexport-test-harness-main.rs deleted file mode 100644 index 2582975e219..00000000000 --- a/src/test/run-pass/reexport-test-harness-main.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/refer-to-other-statics-by-value.rs b/src/test/run-pass/refer-to-other-statics-by-value.rs deleted file mode 100644 index 90f1980f858..00000000000 --- a/src/test/run-pass/refer-to-other-statics-by-value.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -static A: usize = 42; -static B: usize = A; - -fn main() { - assert_eq!(B, 42); -} diff --git a/src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs b/src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs deleted file mode 100644 index 4221ebfdffb..00000000000 --- a/src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/regions/regions-addr-of-ret.rs b/src/test/run-pass/regions/regions-addr-of-ret.rs deleted file mode 100644 index e5dcd6db033..00000000000 --- a/src/test/run-pass/regions/regions-addr-of-ret.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -fn f(x: &isize) -> &isize { - return &*x; -} - -pub fn main() { - let three = &3; - println!("{}", *f(three)); -} diff --git a/src/test/run-pass/regions/regions-assoc-type-region-bound.rs b/src/test/run-pass/regions/regions-assoc-type-region-bound.rs deleted file mode 100644 index cbb7d1726d9..00000000000 --- a/src/test/run-pass/regions/regions-assoc-type-region-bound.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/regions/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions/regions-assoc-type-static-bound.rs deleted file mode 100644 index 1458787ea65..00000000000 --- a/src/test/run-pass/regions/regions-assoc-type-static-bound.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/regions/regions-borrow-at.rs b/src/test/run-pass/regions/regions-borrow-at.rs deleted file mode 100644 index 355e8c91455..00000000000 --- a/src/test/run-pass/regions/regions-borrow-at.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/regions/regions-borrow-evec-fixed.rs b/src/test/run-pass/regions/regions-borrow-evec-fixed.rs deleted file mode 100644 index ed828312b46..00000000000 --- a/src/test/run-pass/regions/regions-borrow-evec-fixed.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/regions/regions-borrow-evec-uniq.rs b/src/test/run-pass/regions/regions-borrow-evec-uniq.rs deleted file mode 100644 index bbf7ba79e2a..00000000000 --- a/src/test/run-pass/regions/regions-borrow-evec-uniq.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/regions/regions-borrow-uniq.rs b/src/test/run-pass/regions/regions-borrow-uniq.rs deleted file mode 100644 index 3bf049c1511..00000000000 --- a/src/test/run-pass/regions/regions-borrow-uniq.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/regions/regions-bot.rs b/src/test/run-pass/regions/regions-bot.rs deleted file mode 100644 index 58016293640..00000000000 --- a/src/test/run-pass/regions/regions-bot.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs deleted file mode 100644 index 2c750379933..00000000000 --- a/src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/regions/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions/regions-bound-lists-feature-gate.rs deleted file mode 100644 index 3815498f86f..00000000000 --- a/src/test/run-pass/regions/regions-bound-lists-feature-gate.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs b/src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs deleted file mode 100644 index 4b47ed8c6ae..00000000000 --- a/src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/regions/regions-copy-closure.rs b/src/test/run-pass/regions/regions-copy-closure.rs deleted file mode 100644 index 43640079777..00000000000 --- a/src/test/run-pass/regions/regions-copy-closure.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/regions/regions-creating-enums2.rs b/src/test/run-pass/regions/regions-creating-enums2.rs deleted file mode 100644 index 7b16fb1a8e0..00000000000 --- a/src/test/run-pass/regions/regions-creating-enums2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/regions/regions-creating-enums5.rs b/src/test/run-pass/regions/regions-creating-enums5.rs deleted file mode 100644 index ad3d9748bf0..00000000000 --- a/src/test/run-pass/regions/regions-creating-enums5.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/regions/regions-debruijn-of-object.rs b/src/test/run-pass/regions/regions-debruijn-of-object.rs deleted file mode 100644 index 0b5510489fb..00000000000 --- a/src/test/run-pass/regions/regions-debruijn-of-object.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/regions/regions-dependent-addr-of.rs b/src/test/run-pass/regions/regions-dependent-addr-of.rs deleted file mode 100644 index 0a7e6625c73..00000000000 --- a/src/test/run-pass/regions/regions-dependent-addr-of.rs +++ /dev/null @@ -1,113 +0,0 @@ -// 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/src/test/run-pass/regions/regions-dependent-autofn.rs b/src/test/run-pass/regions/regions-dependent-autofn.rs deleted file mode 100644 index 246dbb5563c..00000000000 --- a/src/test/run-pass/regions/regions-dependent-autofn.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-dependent-autoslice.rs b/src/test/run-pass/regions/regions-dependent-autoslice.rs deleted file mode 100644 index 4c5b35ec455..00000000000 --- a/src/test/run-pass/regions/regions-dependent-autoslice.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/regions/regions-dependent-let-ref.rs b/src/test/run-pass/regions/regions-dependent-let-ref.rs deleted file mode 100644 index 94e3df4b3f1..00000000000 --- a/src/test/run-pass/regions/regions-dependent-let-ref.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs deleted file mode 100644 index fe50a7dd1be..00000000000 --- a/src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/regions/regions-early-bound-trait-param.rs b/src/test/run-pass/regions/regions-early-bound-trait-param.rs deleted file mode 100644 index cc2bde78d85..00000000000 --- a/src/test/run-pass/regions/regions-early-bound-trait-param.rs +++ /dev/null @@ -1,134 +0,0 @@ -// 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/src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs b/src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs deleted file mode 100644 index a778dae1ed3..00000000000 --- a/src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/regions/regions-early-bound-used-in-bound.rs b/src/test/run-pass/regions/regions-early-bound-used-in-bound.rs deleted file mode 100644 index 6ccc99e845d..00000000000 --- a/src/test/run-pass/regions/regions-early-bound-used-in-bound.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs b/src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs deleted file mode 100644 index d58c17ad9c8..00000000000 --- a/src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/regions/regions-escape-into-other-fn.rs b/src/test/run-pass/regions/regions-escape-into-other-fn.rs deleted file mode 100644 index fd4690463e6..00000000000 --- a/src/test/run-pass/regions/regions-escape-into-other-fn.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/regions/regions-expl-self.rs b/src/test/run-pass/regions/regions-expl-self.rs deleted file mode 100644 index f7315d628a5..00000000000 --- a/src/test/run-pass/regions/regions-expl-self.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-fn-subtyping-2.rs b/src/test/run-pass/regions/regions-fn-subtyping-2.rs deleted file mode 100644 index 83949ddba3d..00000000000 --- a/src/test/run-pass/regions/regions-fn-subtyping-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/regions/regions-fn-subtyping.rs b/src/test/run-pass/regions/regions-fn-subtyping.rs deleted file mode 100644 index 9570359c69e..00000000000 --- a/src/test/run-pass/regions/regions-fn-subtyping.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs b/src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs deleted file mode 100644 index f464cab7554..00000000000 --- a/src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs b/src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs deleted file mode 100644 index 5d8ad932ed6..00000000000 --- a/src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-borrow-scope-view.rs b/src/test/run-pass/regions/regions-infer-borrow-scope-view.rs deleted file mode 100644 index 349b5204434..00000000000 --- a/src/test/run-pass/regions/regions-infer-borrow-scope-view.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs b/src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs deleted file mode 100644 index f0ecc5de545..00000000000 --- a/src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-borrow-scope.rs b/src/test/run-pass/regions/regions-infer-borrow-scope.rs deleted file mode 100644 index 453973d9c58..00000000000 --- a/src/test/run-pass/regions/regions-infer-borrow-scope.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-call-2.rs b/src/test/run-pass/regions/regions-infer-call-2.rs deleted file mode 100644 index a288d2e4d6e..00000000000 --- a/src/test/run-pass/regions/regions-infer-call-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-call.rs b/src/test/run-pass/regions/regions-infer-call.rs deleted file mode 100644 index 248f9e923d3..00000000000 --- a/src/test/run-pass/regions/regions-infer-call.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs b/src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs deleted file mode 100644 index fbd89501559..00000000000 --- a/src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs b/src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs deleted file mode 100644 index 31a48b4adcf..00000000000 --- a/src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs b/src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs deleted file mode 100644 index 6aa5d8217a4..00000000000 --- a/src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/regions/regions-infer-static-from-proc.rs b/src/test/run-pass/regions/regions-infer-static-from-proc.rs deleted file mode 100644 index 39501e2d697..00000000000 --- a/src/test/run-pass/regions/regions-infer-static-from-proc.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/regions/regions-issue-21422.rs b/src/test/run-pass/regions/regions-issue-21422.rs deleted file mode 100644 index 198b7146647..00000000000 --- a/src/test/run-pass/regions/regions-issue-21422.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/regions/regions-issue-22246.rs b/src/test/run-pass/regions/regions-issue-22246.rs deleted file mode 100644 index 0858833678b..00000000000 --- a/src/test/run-pass/regions/regions-issue-22246.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs b/src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs deleted file mode 100644 index c8106f32c65..00000000000 --- a/src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs b/src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs deleted file mode 100644 index b6a89e29ecc..00000000000 --- a/src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/regions/regions-link-fn-args.rs b/src/test/run-pass/regions/regions-link-fn-args.rs deleted file mode 100644 index 231407b226e..00000000000 --- a/src/test/run-pass/regions/regions-link-fn-args.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-lub-ref-ref-rc.rs b/src/test/run-pass/regions/regions-lub-ref-ref-rc.rs deleted file mode 100644 index 96c71b084b1..00000000000 --- a/src/test/run-pass/regions/regions-lub-ref-ref-rc.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/regions/regions-mock-codegen.rs b/src/test/run-pass/regions/regions-mock-codegen.rs deleted file mode 100644 index 521ef3f6a4b..00000000000 --- a/src/test/run-pass/regions/regions-mock-codegen.rs +++ /dev/null @@ -1,56 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -// pretty-expanded FIXME #23616 - -#![feature(allocator_api)] - -use std::alloc::{Alloc, Global, Layout, handle_alloc_error}; -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<'a>(_bcx : &'a arena) -> &'a Bcx<'a> { - 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: 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: ccx }; - return g(&fcx); -} - -pub fn main() { - let ccx = Ccx { x: 0 }; - f(&ccx); -} diff --git a/src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs deleted file mode 100644 index aafab5d86b8..00000000000 --- a/src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs deleted file mode 100644 index 76706a82781..00000000000 --- a/src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/regions/regions-nullary-variant.rs b/src/test/run-pass/regions/regions-nullary-variant.rs deleted file mode 100644 index 82470af82fa..00000000000 --- a/src/test/run-pass/regions/regions-nullary-variant.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/regions/regions-params.rs b/src/test/run-pass/regions/regions-params.rs deleted file mode 100644 index 04f3b8eaf57..00000000000 --- a/src/test/run-pass/regions/regions-params.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs b/src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs deleted file mode 100644 index 948b11e0f30..00000000000 --- a/src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs b/src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs deleted file mode 100644 index ca52659c4db..00000000000 --- a/src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/regions/regions-refcell.rs b/src/test/run-pass/regions/regions-refcell.rs deleted file mode 100644 index 39ad0c53f1e..00000000000 --- a/src/test/run-pass/regions/regions-refcell.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs b/src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs deleted file mode 100644 index aec05161c1a..00000000000 --- a/src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/regions/regions-return-interior-of-option.rs b/src/test/run-pass/regions/regions-return-interior-of-option.rs deleted file mode 100644 index 2dc91ec84f5..00000000000 --- a/src/test/run-pass/regions/regions-return-interior-of-option.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/regions/regions-scope-chain-example.rs b/src/test/run-pass/regions/regions-scope-chain-example.rs deleted file mode 100644 index 2beb20add32..00000000000 --- a/src/test/run-pass/regions/regions-scope-chain-example.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/regions/regions-self-impls.rs b/src/test/run-pass/regions/regions-self-impls.rs deleted file mode 100644 index 80b88568e42..00000000000 --- a/src/test/run-pass/regions/regions-self-impls.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/regions/regions-self-in-enums.rs b/src/test/run-pass/regions/regions-self-in-enums.rs deleted file mode 100644 index c2e4b2ff10d..00000000000 --- a/src/test/run-pass/regions/regions-self-in-enums.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/regions/regions-simple.rs b/src/test/run-pass/regions/regions-simple.rs deleted file mode 100644 index fff1b47f53f..00000000000 --- a/src/test/run-pass/regions/regions-simple.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -pub fn main() { - let mut x: isize = 3; - let y: &mut isize = &mut x; - *y = 5; - println!("{}", *y); -} diff --git a/src/test/run-pass/regions/regions-static-closure.rs b/src/test/run-pass/regions/regions-static-closure.rs deleted file mode 100644 index 09cd5622032..00000000000 --- a/src/test/run-pass/regions/regions-static-closure.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/regions/regions-trait-object-1.rs b/src/test/run-pass/regions/regions-trait-object-1.rs deleted file mode 100644 index 679bf4dd811..00000000000 --- a/src/test/run-pass/regions/regions-trait-object-1.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// This is a regression test for something that only came up while -// attempting to bootstrap libsyntax; it is adapted from -// `syntax::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/src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs b/src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs deleted file mode 100644 index f10d5a25f16..00000000000 --- a/src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs b/src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs deleted file mode 100644 index 9316aa15d32..00000000000 --- a/src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/repeat-expr-in-static.rs b/src/test/run-pass/repeat-expr-in-static.rs deleted file mode 100644 index 0b895379330..00000000000 --- a/src/test/run-pass/repeat-expr-in-static.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/repr_c_int_align.rs b/src/test/run-pass/repr_c_int_align.rs deleted file mode 100644 index fdd14fc2dbe..00000000000 --- a/src/test/run-pass/repr_c_int_align.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/resolve-issue-2428.rs b/src/test/run-pass/resolve-issue-2428.rs deleted file mode 100644 index 5f3473e9feb..00000000000 --- a/src/test/run-pass/resolve-issue-2428.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/resolve-pseudo-shadowing.rs b/src/test/run-pass/resolve-pseudo-shadowing.rs deleted file mode 100644 index 85c684ca032..00000000000 --- a/src/test/run-pass/resolve-pseudo-shadowing.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/run-pass/resource-assign-is-not-copy.rs deleted file mode 100644 index c1de139a9a9..00000000000 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs deleted file mode 100644 index c4756a21a00..00000000000 --- a/src/test/run-pass/resource-destruct.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/result-opt-conversions.rs b/src/test/run-pass/result-opt-conversions.rs deleted file mode 100644 index 57f258aab65..00000000000 --- a/src/test/run-pass/result-opt-conversions.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/ret-bang.rs b/src/test/run-pass/ret-bang.rs deleted file mode 100644 index 6618992e036..00000000000 --- a/src/test/run-pass/ret-bang.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/ret-none.rs b/src/test/run-pass/ret-none.rs deleted file mode 100644 index d595506e336..00000000000 --- a/src/test/run-pass/ret-none.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/return-nil.rs b/src/test/run-pass/return-nil.rs deleted file mode 100644 index fd5203ff0ed..00000000000 --- a/src/test/run-pass/return-nil.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn f() { let x: () = (); return x; } - -pub fn main() { let _x = f(); } diff --git a/src/test/run-pass/rfcs/rfc-1014-2.rs b/src/test/run-pass/rfcs/rfc-1014-2.rs deleted file mode 100644 index 5be092204d7..00000000000 --- a/src/test/run-pass/rfcs/rfc-1014-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 world"); -} - -#[cfg(not(windows))] -fn main() {} diff --git a/src/test/run-pass/rfcs/rfc-1014.rs b/src/test/run-pass/rfcs/rfc-1014.rs deleted file mode 100644 index 41a036958bf..00000000000 --- a/src/test/run-pass/rfcs/rfc-1014.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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 world"); -} diff --git a/src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs deleted file mode 100644 index ea3ad7aed49..00000000000 --- a/src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs deleted file mode 100644 index e98582cbce3..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -use std::error::Error; - -fn main() -> Result<(), Box> { - Ok(()) -} diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs deleted file mode 100644 index bac695d4e79..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs +++ /dev/null @@ -1,2 +0,0 @@ -// run-pass -fn main() {} diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs deleted file mode 100644 index 9c2270bf827..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(process_exitcode_placeholder)] - -use std::process::ExitCode; - -fn main() -> ExitCode { - ExitCode::SUCCESS -} diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs deleted file mode 100644 index 79cfba011c0..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -#![feature(termination_trait_lib)] - -fn main() -> impl std::process::Termination { } diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs deleted file mode 100644 index b0e932e1fe0..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -use std::io::Error; - -fn main() -> Result<(), Box> { - Ok(()) -} diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs deleted file mode 100644 index 30f36c24489..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -use std::io::Error; - -fn main() -> Result<(), Error> { - Ok(()) -} diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs deleted file mode 100644 index f0591c38c00..00000000000 --- a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -fn main() -> Result<(), &'static str> { - Ok(()) -} diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs deleted file mode 100644 index b3be41599a5..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs deleted file mode 100644 index d5bca6a2474..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs deleted file mode 100644 index 52fbb90ed54..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs deleted file mode 100644 index a5a24a80634..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs deleted file mode 100644 index 0207f607be8..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs +++ /dev/null @@ -1,249 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs deleted file mode 100644 index 9379753598e..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs deleted file mode 100644 index 580e67513b3..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -pub fn main() { - let i = 5; - match &&&&i { - 1 ..= 3 => panic!(), - 3 ..= 8 => {}, - _ => panic!(), - } -} diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs deleted file mode 100644 index b74e45c9328..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs deleted file mode 100644 index 3b9d07610d2..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs deleted file mode 100644 index 939a3c4a1fd..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![feature(slice_patterns)] - -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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs deleted file mode 100644 index 5a00e5b6823..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs deleted file mode 100644 index 0cf9ba1b4ca..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs b/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs deleted file mode 100644 index 4c22aa2d718..00000000000 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.rs b/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.rs deleted file mode 100644 index 02d4851ab2a..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.rs +++ /dev/null @@ -1,42 +0,0 @@ -// run-pass -#![feature(crate_in_paths)] -#![allow(dead_code)] -use crate::m::f; -use crate as root; - -mod m { - pub fn f() -> u8 { 1 } - pub fn g() -> u8 { 2 } - pub fn h() -> u8 { 3 } - - // OK, visibilities are implicitly absolute like imports - pub(in crate::m) struct S; -} - -mod n { - use crate::m::f; - use crate as root; - pub fn check() { - assert_eq!(f(), 1); - assert_eq!(crate::m::g(), 2); - assert_eq!(root::m::h(), 3); - } -} - -mod p { - use {super::f, crate::m::g, self::root::m::h}; - use crate as root; - pub fn check() { - assert_eq!(f(), 1); - assert_eq!(g(), 2); - assert_eq!(h(), 3); - } -} - -fn main() { - assert_eq!(f(), 1); - assert_eq!(crate::m::g(), 2); - assert_eq!(root::m::h(), 3); - n::check(); - p::check(); -} diff --git a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.stderr b/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.stderr deleted file mode 100644 index 12f799f6e47..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `crate_in_paths` has been stable since 1.30.0 and no longer requires an attribute to enable - --> $DIR/crate-path-absolute.rs:2:12 - | -LL | #![feature(crate_in_paths)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(stable_features)]` on by default - diff --git a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs b/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs deleted file mode 100644 index 5fa8d7b2a49..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -#![feature(crate_in_paths)] -#![feature(crate_visibility_modifier)] -#![allow(dead_code)] -mod m { - pub struct Z; - pub struct S1(crate (::m::Z)); // OK - pub struct S2((crate ::m::Z)); // OK - pub struct S3(crate ::m::Z); // OK - pub struct S4(crate crate::m::Z); // OK -} - -fn main() { - crate struct S; // OK (item in statement position) -} diff --git a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.stderr b/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.stderr deleted file mode 100644 index 23a0e544554..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `crate_in_paths` has been stable since 1.30.0 and no longer requires an attribute to enable - --> $DIR/crate-path-visibility-ambiguity.rs:2:12 - | -LL | #![feature(crate_in_paths)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(stable_features)]` on by default - diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs deleted file mode 100644 index 07e70648452..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[derive(Debug, PartialEq)] -pub struct S; - -#[derive(Debug)] -pub struct Z; - -pub trait Tr<'a> {} diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs deleted file mode 100644 index 566b3581046..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(dead_code)] -// aux-build:xcrate.rs -// compile-flags:--extern xcrate -// edition:2018 - -#![allow(unused_imports)] - -use xcrate::Z; - -fn f() { - use xcrate; - use xcrate as ycrate; - let s = xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = ycrate::Z; - assert_eq!(format!("{:?}", z), "Z"); -} - -fn main() { - let s = ::xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = Z; - assert_eq!(format!("{:?}", z), "Z"); -} diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/test.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/test.rs deleted file mode 100644 index 7ed82e32a0a..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/test.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// Check that `#[test]` works with extern-absolute-paths enabled. -// -// Regression test for #47075. - -// edition:2018 -// compile-flags: --test - -#[test] -fn test() {} diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs deleted file mode 100644 index 251406e7604..00000000000 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -// edition:2018 - -// Tests that `core` and `std` are always available. -use core::iter; -use std::io; -// FIXME(eddyb) Add a `meta` crate to the distribution. -// use meta; - -fn main() { - for _ in iter::once(()) { - io::stdout(); - } -} diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs deleted file mode 100644 index 2fe1e05e509..00000000000 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs deleted file mode 100644 index f2fe59668da..00000000000 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs deleted file mode 100644 index 4665225178c..00000000000 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs deleted file mode 100644 index 0ab7e17f87b..00000000000 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs b/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs deleted file mode 100644 index 22f04c58f3b..00000000000 --- a/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs b/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs deleted file mode 100644 index 1ec20c50034..00000000000 --- a/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs +++ /dev/null @@ -1,127 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs deleted file mode 100644 index 6d7bca4da24..00000000000 --- a/src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs deleted file mode 100644 index 17174e22c74..00000000000 --- a/src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs b/src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs deleted file mode 100644 index 405a69c94bf..00000000000 --- a/src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc1623.rs b/src/test/run-pass/rfcs/rfc1623.rs deleted file mode 100644 index adaf25c6bbf..00000000000 --- a/src/test/run-pass/rfcs/rfc1623.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs deleted file mode 100644 index c1c5b70bc04..00000000000 --- a/src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic -#![crate_type = "staticlib"] - -#[no_mangle] -pub extern "C" fn foo(x:i32) -> i32 { x } diff --git a/src/test/run-pass/rfcs/rfc1717/library-override.rs b/src/test/run-pass/rfcs/rfc1717/library-override.rs deleted file mode 100644 index 014ccac31b7..00000000000 --- a/src/test/run-pass/rfcs/rfc1717/library-override.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/rfcs/rfc1857-drop-order.rs b/src/test/run-pass/rfcs/rfc1857-drop-order.rs deleted file mode 100644 index 7923aa7c0e2..00000000000 --- a/src/test/run-pass/rfcs/rfc1857-drop-order.rs +++ /dev/null @@ -1,224 +0,0 @@ -// 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/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs deleted file mode 100644 index 3fc631be60e..00000000000 --- a/src/test/run-pass/running-with-no-runtime.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/rustc-rust-log.rs b/src/test/run-pass/rustc-rust-log.rs deleted file mode 100644 index 1c4252b23ea..00000000000 --- a/src/test/run-pass/rustc-rust-log.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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 - -// rustc-env:RUSTC_LOG=debug - -fn main() {} diff --git a/src/test/run-pass/rvalue-static-promotion.rs b/src/test/run-pass/rvalue-static-promotion.rs deleted file mode 100644 index 2d7e4ab3989..00000000000 --- a/src/test/run-pass/rvalue-static-promotion.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/segfault-no-out-of-stack.rs b/src/test/run-pass/segfault-no-out-of-stack.rs deleted file mode 100644 index 626de4ed5b6..00000000000 --- a/src/test/run-pass/segfault-no-out-of-stack.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/semistatement-in-lambda.rs b/src/test/run-pass/semistatement-in-lambda.rs deleted file mode 100644 index ebd55e0ba02..00000000000 --- a/src/test/run-pass/semistatement-in-lambda.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs b/src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs deleted file mode 100644 index 73fb5e8f3c4..00000000000 --- a/src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[no_mangle] -pub extern "C" fn foo() -> usize { - 1234 -} diff --git a/src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs b/src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs deleted file mode 100644 index 64e34a56da4..00000000000 --- a/src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[inline] -pub fn cci_fn() -> usize { - 1200 -} - -pub const CCI_CONST: usize = 34; diff --git a/src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs b/src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs deleted file mode 100644 index 1536228c265..00000000000 --- a/src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-cci.rs b/src/test/run-pass/sepcomp/sepcomp-cci.rs deleted file mode 100644 index 02bbab30e9c..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-cci.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-extern.rs b/src/test/run-pass/sepcomp/sepcomp-extern.rs deleted file mode 100644 index c4ccf23c47a..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-extern.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs b/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs deleted file mode 100644 index f56769e2b8c..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-fns.rs b/src/test/run-pass/sepcomp/sepcomp-fns.rs deleted file mode 100644 index a432c89606e..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-fns.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-lib-lto.rs b/src/test/run-pass/sepcomp/sepcomp-lib-lto.rs deleted file mode 100644 index 164ae79c254..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-lib-lto.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 -// 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/src/test/run-pass/sepcomp/sepcomp-lib.rs b/src/test/run-pass/sepcomp/sepcomp-lib.rs deleted file mode 100644 index 728dc078b7e..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-statics.rs b/src/test/run-pass/sepcomp/sepcomp-statics.rs deleted file mode 100644 index 5457c8a0ae9..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-statics.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/sepcomp/sepcomp-unwind.rs b/src/test/run-pass/sepcomp/sepcomp-unwind.rs deleted file mode 100644 index 50a4e043943..00000000000 --- a/src/test/run-pass/sepcomp/sepcomp-unwind.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/seq-compare.rs b/src/test/run-pass/seq-compare.rs deleted file mode 100644 index 4078326b559..00000000000 --- a/src/test/run-pass/seq-compare.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/shadow.rs b/src/test/run-pass/shadow.rs deleted file mode 100644 index 2495c8f47e7..00000000000 --- a/src/test/run-pass/shadow.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/shadowed-use-visibility.rs b/src/test/run-pass/shadowed-use-visibility.rs deleted file mode 100644 index 350fbfeaeb5..00000000000 --- a/src/test/run-pass/shadowed-use-visibility.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/shebang.rs b/src/test/run-pass/shebang.rs deleted file mode 100644 index 3d3ba468be9..00000000000 --- a/src/test/run-pass/shebang.rs +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env rustx - -// run-pass - -pub fn main() { println!("Hello World"); } diff --git a/src/test/run-pass/signal-alternate-stack-cleanup.rs b/src/test/run-pass/signal-alternate-stack-cleanup.rs deleted file mode 100644 index 787ff51799a..00000000000 --- a/src/test/run-pass/signal-alternate-stack-cleanup.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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 - -#![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/src/test/run-pass/signal-exit-status.rs b/src/test/run-pass/signal-exit-status.rs deleted file mode 100644 index bd34a218160..00000000000 --- a/src/test/run-pass/signal-exit-status.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/sigpipe-should-be-ignored.rs b/src/test/run-pass/sigpipe-should-be-ignored.rs deleted file mode 100644 index f472029b820..00000000000 --- a/src/test/run-pass/sigpipe-should-be-ignored.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/simd/simd-generics.rs b/src/test/run-pass/simd/simd-generics.rs deleted file mode 100644 index ab6caee9d7b..00000000000 --- a/src/test/run-pass/simd/simd-generics.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-float-math.rs b/src/test/run-pass/simd/simd-intrinsic-float-math.rs deleted file mode 100644 index 220a59535ca..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-float-math.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-float-minmax.rs b/src/test/run-pass/simd/simd-intrinsic-float-minmax.rs deleted file mode 100644 index 350bc434935..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-float-minmax.rs +++ /dev/null @@ -1,54 +0,0 @@ -// run-pass -// ignore-emscripten -// min-llvm-version 7.0 -// error-pattern: panicked - -// 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/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs deleted file mode 100644 index b2ddcf023eb..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs +++ /dev/null @@ -1,92 +0,0 @@ -// run-pass -// ignore-emscripten -// min-llvm-version 8.0 - -#![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_value(); - - 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_value(); - const MAX: i32 = i32::max_value(); - - 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/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs deleted file mode 100644 index b67c0ad1eb2..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs +++ /dev/null @@ -1,120 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs b/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs deleted file mode 100644 index b28f742a92e..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs +++ /dev/null @@ -1,61 +0,0 @@ -// run-pass -#![allow(non_camel_case_types)] - -// ignore-emscripten - -// 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_value(), 0, usize::max_value(), usize::max_value()); - - 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/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs b/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs deleted file mode 100644 index 15f232e2c0f..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs +++ /dev/null @@ -1,121 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs b/src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs deleted file mode 100644 index 2b593e1c9b8..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs +++ /dev/null @@ -1,106 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-generic-elements.rs b/src/test/run-pass/simd/simd-intrinsic-generic-elements.rs deleted file mode 100644 index ea3d4b18944..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-elements.rs +++ /dev/null @@ -1,125 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-generic-gather.rs b/src/test/run-pass/simd/simd-intrinsic-generic-gather.rs deleted file mode 100644 index 805caebe5b1..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-gather.rs +++ /dev/null @@ -1,141 +0,0 @@ -// 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/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs deleted file mode 100644 index 4195444a73f..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs +++ /dev/null @@ -1,165 +0,0 @@ -// 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_value(); - 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/src/test/run-pass/simd/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs deleted file mode 100644 index 22bda4fc9d9..00000000000 --- a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs +++ /dev/null @@ -1,173 +0,0 @@ -// run-pass -#![allow(non_camel_case_types)] - -// ignore-emscripten -// ignore-mips behavior of simd_select_bitmask is endian-specific -// ignore-mips64 behavior of simd_select_bitmask is endian-specific -// ignore-powerpc behavior of simd_select_bitmask is endian-specific -// ignore-powerpc64 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); - } -} diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs deleted file mode 100644 index 556013788c3..00000000000 --- a/src/test/run-pass/simd/simd-size-align.rs +++ /dev/null @@ -1,96 +0,0 @@ -// 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/src/test/run-pass/simd/simd-target-feature-mixup.rs b/src/test/run-pass/simd/simd-target-feature-mixup.rs deleted file mode 100644 index 6d7688191b7..00000000000 --- a/src/test/run-pass/simd/simd-target-feature-mixup.rs +++ /dev/null @@ -1,185 +0,0 @@ -// 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/src/test/run-pass/simd/simd-type.rs b/src/test/run-pass/simd/simd-type.rs deleted file mode 100644 index e7b9bfe32f8..00000000000 --- a/src/test/run-pass/simd/simd-type.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/simple-infer.rs b/src/test/run-pass/simple-infer.rs deleted file mode 100644 index 561e4fdec7c..00000000000 --- a/src/test/run-pass/simple-infer.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -#![allow(unused_mut)] - - -pub fn main() { let mut n; n = 1; println!("{}", n); } diff --git a/src/test/run-pass/simple_global_asm.rs b/src/test/run-pass/simple_global_asm.rs deleted file mode 100644 index d95fefebc0f..00000000000 --- a/src/test/run-pass/simple_global_asm.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/size-and-align.rs b/src/test/run-pass/size-and-align.rs deleted file mode 100644 index a32b5de7292..00000000000 --- a/src/test/run-pass/size-and-align.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/sized-borrowed-pointer.rs b/src/test/run-pass/sized-borrowed-pointer.rs deleted file mode 100644 index 319b8026954..00000000000 --- a/src/test/run-pass/sized-borrowed-pointer.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/sized-owned-pointer.rs b/src/test/run-pass/sized-owned-pointer.rs deleted file mode 100644 index 2abf0a1e0c2..00000000000 --- a/src/test/run-pass/sized-owned-pointer.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/sleep.rs b/src/test/run-pass/sleep.rs deleted file mode 100644 index 757578b8475..00000000000 --- a/src/test/run-pass/sleep.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// ignore-emscripten no threads support -// ignore-sgx no thread sleep 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/src/test/run-pass/slowparse-bstring.rs b/src/test/run-pass/slowparse-bstring.rs deleted file mode 100644 index f3a6a668372..00000000000 --- a/src/test/run-pass/slowparse-bstring.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// ignore-tidy-linelength - -// Issue #16624 - -fn main() { b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } diff --git a/src/test/run-pass/slowparse-string.rs b/src/test/run-pass/slowparse-string.rs deleted file mode 100644 index 6ebc61dae78..00000000000 --- a/src/test/run-pass/slowparse-string.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// ignore-tidy-linelength - -// Issue #16624 - -fn main() { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } diff --git a/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs b/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs deleted file mode 100644 index 54d51492ab3..00000000000 --- a/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass - -// Make sure we don't crash with a cycle error during coherence. - -#![feature(specialization)] - -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/src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs b/src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs deleted file mode 100644 index 5cf975b5752..00000000000 --- a/src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![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 {} // use the provided method - -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/src/test/run-pass/specialization/auxiliary/go_trait.rs b/src/test/run-pass/specialization/auxiliary/go_trait.rs deleted file mode 100644 index aa0ec22896d..00000000000 --- a/src/test/run-pass/specialization/auxiliary/go_trait.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![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/src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs b/src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs deleted file mode 100644 index 8caa8524fb9..00000000000 --- a/src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs +++ /dev/null @@ -1,72 +0,0 @@ -#![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/src/test/run-pass/specialization/cross-crate-defaults.rs b/src/test/run-pass/specialization/cross-crate-defaults.rs deleted file mode 100644 index 79cb6594397..00000000000 --- a/src/test/run-pass/specialization/cross-crate-defaults.rs +++ /dev/null @@ -1,41 +0,0 @@ -// run-pass - -// aux-build:cross_crates_defaults.rs - -#![feature(specialization)] - -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/src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs deleted file mode 100644 index 15550bcce2a..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] - -// aux-build:go_trait.rs - -#![feature(specialization)] - -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/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs deleted file mode 100644 index c065593b432..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![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/src/test/run-pass/specialization/defaultimpl/out-of-order.rs b/src/test/run-pass/specialization/defaultimpl/out-of-order.rs deleted file mode 100644 index f9c73a19cfa..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/out-of-order.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -// Test that you can list the more specific impl before the more general one. - -#![feature(specialization)] - -trait Foo { - type Out; -} - -impl Foo for bool { - type Out = (); -} - -default impl Foo for T { - type Out = bool; -} - -fn main() {} diff --git a/src/test/run-pass/specialization/defaultimpl/overlap-projection.rs b/src/test/run-pass/specialization/defaultimpl/overlap-projection.rs deleted file mode 100644 index ed38bb3fc3a..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/overlap-projection.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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)] - -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/src/test/run-pass/specialization/defaultimpl/projection.rs b/src/test/run-pass/specialization/defaultimpl/projection.rs deleted file mode 100644 index 897a7aade2f..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/projection.rs +++ /dev/null @@ -1,42 +0,0 @@ -// run-pass -#![allow(dead_code)] - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/issue-50452.rs b/src/test/run-pass/specialization/issue-50452.rs deleted file mode 100644 index 93f081d9558..00000000000 --- a/src/test/run-pass/specialization/issue-50452.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -#![feature(specialization)] - -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/src/test/run-pass/specialization/specialization-allowed-cross-crate.rs b/src/test/run-pass/specialization/specialization-allowed-cross-crate.rs deleted file mode 100644 index 15550bcce2a..00000000000 --- a/src/test/run-pass/specialization/specialization-allowed-cross-crate.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] - -// aux-build:go_trait.rs - -#![feature(specialization)] - -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/src/test/run-pass/specialization/specialization-assoc-fns.rs b/src/test/run-pass/specialization/specialization-assoc-fns.rs deleted file mode 100644 index b6a7a48972a..00000000000 --- a/src/test/run-pass/specialization/specialization-assoc-fns.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass - -// Test that non-method associated functions can be specialized - -#![feature(specialization)] - -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/src/test/run-pass/specialization/specialization-basics.rs b/src/test/run-pass/specialization/specialization-basics.rs deleted file mode 100644 index 6c359e51bc2..00000000000 --- a/src/test/run-pass/specialization/specialization-basics.rs +++ /dev/null @@ -1,98 +0,0 @@ -// run-pass - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs b/src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs deleted file mode 100644 index f744b16de7a..00000000000 --- a/src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/specialization/specialization-cross-crate.rs b/src/test/run-pass/specialization/specialization-cross-crate.rs deleted file mode 100644 index fa63c866329..00000000000 --- a/src/test/run-pass/specialization/specialization-cross-crate.rs +++ /dev/null @@ -1,50 +0,0 @@ -// run-pass - -// aux-build:specialization_cross_crate.rs - -#![feature(specialization)] - -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/src/test/run-pass/specialization/specialization-default-methods.rs b/src/test/run-pass/specialization/specialization-default-methods.rs deleted file mode 100644 index 5d65a0457e7..00000000000 --- a/src/test/run-pass/specialization/specialization-default-methods.rs +++ /dev/null @@ -1,86 +0,0 @@ -// run-pass - -#![feature(specialization)] - -// 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 - -// use the provided method -impl Bar for T {} - -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/src/test/run-pass/specialization/specialization-on-projection.rs b/src/test/run-pass/specialization/specialization-on-projection.rs deleted file mode 100644 index 5606eaea307..00000000000 --- a/src/test/run-pass/specialization/specialization-on-projection.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -#![allow(dead_code)] - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/specialization-out-of-order.rs b/src/test/run-pass/specialization/specialization-out-of-order.rs deleted file mode 100644 index 94e764f7636..00000000000 --- a/src/test/run-pass/specialization/specialization-out-of-order.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -// Test that you can list the more specific impl before the more general one. - -#![feature(specialization)] - -trait Foo { - type Out; -} - -impl Foo for bool { - type Out = (); -} - -impl Foo for T { - default type Out = bool; -} - -fn main() {} diff --git a/src/test/run-pass/specialization/specialization-overlap-projection.rs b/src/test/run-pass/specialization/specialization-overlap-projection.rs deleted file mode 100644 index 00b83c7e7a1..00000000000 --- a/src/test/run-pass/specialization/specialization-overlap-projection.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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)] - -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/src/test/run-pass/specialization/specialization-projection-alias.rs b/src/test/run-pass/specialization/specialization-projection-alias.rs deleted file mode 100644 index 0081ed455c9..00000000000 --- a/src/test/run-pass/specialization/specialization-projection-alias.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/specialization-projection.rs b/src/test/run-pass/specialization/specialization-projection.rs deleted file mode 100644 index 86cdccf131e..00000000000 --- a/src/test/run-pass/specialization/specialization-projection.rs +++ /dev/null @@ -1,42 +0,0 @@ -// run-pass -#![allow(dead_code)] - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/specialization-super-traits.rs b/src/test/run-pass/specialization/specialization-super-traits.rs deleted file mode 100644 index a0f71d87693..00000000000 --- a/src/test/run-pass/specialization/specialization-super-traits.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -#![feature(specialization)] - -// 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/src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs b/src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs deleted file mode 100644 index 2e32e3ff02d..00000000000 --- a/src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs +++ /dev/null @@ -1,33 +0,0 @@ -// run-pass - -#![feature(specialization)] - -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/src/test/run-pass/specialization/specialization-translate-projections-with-params.rs b/src/test/run-pass/specialization/specialization-translate-projections-with-params.rs deleted file mode 100644 index bdc6501df44..00000000000 --- a/src/test/run-pass/specialization/specialization-translate-projections-with-params.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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)] - -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/src/test/run-pass/specialization/specialization-translate-projections.rs b/src/test/run-pass/specialization/specialization-translate-projections.rs deleted file mode 100644 index fcccb67902e..00000000000 --- a/src/test/run-pass/specialization/specialization-translate-projections.rs +++ /dev/null @@ -1,33 +0,0 @@ -// run-pass - -// Ensure that provided items are inherited properly even when impls vary in -// type parameters *and* rely on projections. - -#![feature(specialization)] - -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/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs deleted file mode 100644 index 74f112464c7..00000000000 --- a/src/test/run-pass/sse2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 -- whitelisted 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/src/test/run-pass/stable-addr-of.rs b/src/test/run-pass/stable-addr-of.rs deleted file mode 100644 index 99839166e30..00000000000 --- a/src/test/run-pass/stable-addr-of.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// Issue #2040 - - -pub fn main() { - let foo: isize = 1; - assert_eq!(&foo as *const isize, &foo as *const isize); -} diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs deleted file mode 100644 index 9018ff4bfc2..00000000000 --- a/src/test/run-pass/stack-probes-lto.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs deleted file mode 100644 index 1ab1d6df66d..00000000000 --- a/src/test/run-pass/stack-probes.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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 - -use std::mem; -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(&[]), - "child-thread" => thread::spawn(|| recurse(&[])).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: &[u64]) { - unsafe { black_box(array.as_ptr() as u64); } - #[allow(deprecated)] - let local: [_; 1024] = unsafe { mem::uninitialized() }; - 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/src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs b/src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs deleted file mode 100644 index 4dfc25764a4..00000000000 --- a/src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs +++ /dev/null @@ -1,4 +0,0 @@ -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/src/test/run-pass/statics/auxiliary/static-methods-crate.rs b/src/test/run-pass/statics/auxiliary/static-methods-crate.rs deleted file mode 100644 index 7ff3bc0dd2a..00000000000 --- a/src/test/run-pass/statics/auxiliary/static-methods-crate.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![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/src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs b/src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs deleted file mode 100644 index 8d0f7f61ced..00000000000 --- a/src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs b/src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs deleted file mode 100644 index b8aed2c5f54..00000000000 --- a/src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/src/test/run-pass/statics/auxiliary/static_mut_xc.rs b/src/test/run-pass/statics/auxiliary/static_mut_xc.rs deleted file mode 100644 index 264a2243adc..00000000000 --- a/src/test/run-pass/statics/auxiliary/static_mut_xc.rs +++ /dev/null @@ -1 +0,0 @@ -pub static mut a: isize = 3; diff --git a/src/test/run-pass/statics/static-fn-inline-xc.rs b/src/test/run-pass/statics/static-fn-inline-xc.rs deleted file mode 100644 index a400b9c8d56..00000000000 --- a/src/test/run-pass/statics/static-fn-inline-xc.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/statics/static-fn-trait-xc.rs b/src/test/run-pass/statics/static-fn-trait-xc.rs deleted file mode 100644 index 1d3126128c9..00000000000 --- a/src/test/run-pass/statics/static-fn-trait-xc.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/statics/static-function-pointer-xc.rs b/src/test/run-pass/statics/static-function-pointer-xc.rs deleted file mode 100644 index 2d063a751ca..00000000000 --- a/src/test/run-pass/statics/static-function-pointer-xc.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/statics/static-function-pointer.rs b/src/test/run-pass/statics/static-function-pointer.rs deleted file mode 100644 index 6c52dfecdec..00000000000 --- a/src/test/run-pass/statics/static-function-pointer.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/statics/static-impl.rs b/src/test/run-pass/statics/static-impl.rs deleted file mode 100644 index e7bdb38ee62..00000000000 --- a/src/test/run-pass/statics/static-impl.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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/src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs b/src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs deleted file mode 100644 index cd3ccfee06f..00000000000 --- a/src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/statics/static-method-xcrate.rs b/src/test/run-pass/statics/static-method-xcrate.rs deleted file mode 100644 index 1d1cb381095..00000000000 --- a/src/test/run-pass/statics/static-method-xcrate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/statics/static-methods-in-traits.rs b/src/test/run-pass/statics/static-methods-in-traits.rs deleted file mode 100644 index ff76d4e4a20..00000000000 --- a/src/test/run-pass/statics/static-methods-in-traits.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/statics/static-methods-in-traits2.rs b/src/test/run-pass/statics/static-methods-in-traits2.rs deleted file mode 100644 index 2c43ff6a788..00000000000 --- a/src/test/run-pass/statics/static-methods-in-traits2.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/statics/static-mut-foreign.rs b/src/test/run-pass/statics/static-mut-foreign.rs deleted file mode 100644 index 5d6fa416b98..00000000000 --- a/src/test/run-pass/statics/static-mut-foreign.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/statics/static-mut-xc.rs b/src/test/run-pass/statics/static-mut-xc.rs deleted file mode 100644 index 1d172d26a59..00000000000 --- a/src/test/run-pass/statics/static-mut-xc.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/statics/static-recursive.rs b/src/test/run-pass/statics/static-recursive.rs deleted file mode 100644 index 95dadc81f81..00000000000 --- a/src/test/run-pass/statics/static-recursive.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/stdio-is-blocking.rs b/src/test/run-pass/stdio-is-blocking.rs deleted file mode 100644 index e96406e46b5..00000000000 --- a/src/test/run-pass/stdio-is-blocking.rs +++ /dev/null @@ -1,85 +0,0 @@ -// 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/src/test/run-pass/str-concat.rs b/src/test/run-pass/str-concat.rs deleted file mode 100644 index fa2fc97d7b8..00000000000 --- a/src/test/run-pass/str-concat.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -pub fn main() { - let a: String = "hello".to_string(); - let b: String = "world".to_string(); - let s: String = format!("{}{}", a, b); - println!("{}", s.clone()); - assert_eq!(s.as_bytes()[9], 'd' as u8); -} diff --git a/src/test/run-pass/str-multiline.rs b/src/test/run-pass/str-multiline.rs deleted file mode 100644 index 2b2e001d8bb..00000000000 --- a/src/test/run-pass/str-multiline.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -pub fn main() { - let a: String = "this \ -is a test".to_string(); - let b: String = - "this \ - is \ - another \ - test".to_string(); - assert_eq!(a, "this is a test".to_string()); - assert_eq!(b, "this is another test".to_string()); -} diff --git a/src/test/run-pass/string-box-error.rs b/src/test/run-pass/string-box-error.rs deleted file mode 100644 index 11a5bd07c3b..00000000000 --- a/src/test/run-pass/string-box-error.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/string-escapes.rs b/src/test/run-pass/string-escapes.rs deleted file mode 100644 index cee5e27786c..00000000000 --- a/src/test/run-pass/string-escapes.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -fn main() { - let x = "\\\\\ - "; - assert_eq!(x, r"\\"); // extraneous whitespace stripped -} diff --git a/src/test/run-pass/struct-ctor-mangling.rs b/src/test/run-pass/struct-ctor-mangling.rs deleted file mode 100644 index f242cb8457f..00000000000 --- a/src/test/run-pass/struct-ctor-mangling.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/structs-enums/align-enum.rs b/src/test/run-pass/structs-enums/align-enum.rs deleted file mode 100644 index fa872caa3b4..00000000000 --- a/src/test/run-pass/structs-enums/align-enum.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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/src/test/run-pass/structs-enums/align-struct.rs b/src/test/run-pass/structs-enums/align-struct.rs deleted file mode 100644 index 27ef990aa90..00000000000 --- a/src/test/run-pass/structs-enums/align-struct.rs +++ /dev/null @@ -1,245 +0,0 @@ -// 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/src/test/run-pass/structs-enums/auxiliary/cci_class.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class.rs deleted file mode 100644 index de2945d7460..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs deleted file mode 100644 index c3de3150e69..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs deleted file mode 100644 index fb7fad0b5a2..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs deleted file mode 100644 index 85aa3bc8c0d..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs +++ /dev/null @@ -1,41 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs deleted file mode 100644 index 35f93d0c6c8..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs +++ /dev/null @@ -1,25 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs deleted file mode 100644 index dfc3c56ddee..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs +++ /dev/null @@ -1,50 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs b/src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs deleted file mode 100644 index 2d02b591c55..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod animals { - pub trait noisy { - fn speak(&mut self); - } -} diff --git a/src/test/run-pass/structs-enums/auxiliary/empty-struct.rs b/src/test/run-pass/structs-enums/auxiliary/empty-struct.rs deleted file mode 100644 index 93275e7143e..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/empty-struct.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct XEmpty1 {} -pub struct XEmpty2; -pub struct XEmpty7(); - -pub enum XE { - XEmpty3 {}, - XEmpty4, - XEmpty6(), -} diff --git a/src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs deleted file mode 100644 index 55e6b34aca7..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs +++ /dev/null @@ -1,25 +0,0 @@ -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/src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs b/src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs deleted file mode 100644 index d3548c76cf2..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub enum Foo { - A, - B(isize), - C { a: isize }, -} - -impl Foo { - pub fn foo() {} - pub fn bar(&self) {} -} diff --git a/src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs b/src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs deleted file mode 100644 index 9d1e0742e3c..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type="lib"] - -pub struct Au(pub isize); diff --git a/src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs b/src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs deleted file mode 100644 index 3665ae7e8d3..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![crate_type="lib"] - -pub struct S { - pub x: isize, - pub y: isize, -} diff --git a/src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs b/src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs deleted file mode 100644 index e919df611cf..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![crate_name="struct_variant_xc_aux"] -#![crate_type = "lib"] - -#[derive(Copy, Clone)] -pub enum Enum { - Variant(u8), - StructVariant { arg: u8 } -} diff --git a/src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs b/src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs deleted file mode 100644 index bc8879aa37e..00000000000 --- a/src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub struct S { - pub x: isize, - pub y: isize, -} - -pub type S2 = S; diff --git a/src/test/run-pass/structs-enums/borrow-tuple-fields.rs b/src/test/run-pass/structs-enums/borrow-tuple-fields.rs deleted file mode 100644 index b1d8f91646b..00000000000 --- a/src/test/run-pass/structs-enums/borrow-tuple-fields.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs deleted file mode 100644 index bf1ba8a643f..00000000000 --- a/src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs b/src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs deleted file mode 100644 index 55975cbdb53..00000000000 --- a/src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs +++ /dev/null @@ -1,93 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-cast-to-trait.rs b/src/test/run-pass/structs-enums/class-cast-to-trait.rs deleted file mode 100644 index 1019bb30015..00000000000 --- a/src/test/run-pass/structs-enums/class-cast-to-trait.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-dtor.rs b/src/test/run-pass/structs-enums/class-dtor.rs deleted file mode 100644 index ee1cac03c81..00000000000 --- a/src/test/run-pass/structs-enums/class-dtor.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-exports.rs b/src/test/run-pass/structs-enums/class-exports.rs deleted file mode 100644 index ee20887cbfb..00000000000 --- a/src/test/run-pass/structs-enums/class-exports.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs b/src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs deleted file mode 100644 index 5e7830296da..00000000000 --- a/src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs +++ /dev/null @@ -1,107 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs b/src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs deleted file mode 100644 index 31b79517566..00000000000 --- a/src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-implement-traits.rs b/src/test/run-pass/structs-enums/class-implement-traits.rs deleted file mode 100644 index c9e98e21b9e..00000000000 --- a/src/test/run-pass/structs-enums/class-implement-traits.rs +++ /dev/null @@ -1,63 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-method-cross-crate.rs b/src/test/run-pass/structs-enums/class-method-cross-crate.rs deleted file mode 100644 index 519f0685fdf..00000000000 --- a/src/test/run-pass/structs-enums/class-method-cross-crate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-methods-cross-crate.rs b/src/test/run-pass/structs-enums/class-methods-cross-crate.rs deleted file mode 100644 index c342af31351..00000000000 --- a/src/test/run-pass/structs-enums/class-methods-cross-crate.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-methods.rs b/src/test/run-pass/structs-enums/class-methods.rs deleted file mode 100644 index 83f4a5fd39e..00000000000 --- a/src/test/run-pass/structs-enums/class-methods.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs b/src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs deleted file mode 100644 index 0307ba78d02..00000000000 --- a/src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-poly-methods.rs b/src/test/run-pass/structs-enums/class-poly-methods.rs deleted file mode 100644 index da2870b58a4..00000000000 --- a/src/test/run-pass/structs-enums/class-poly-methods.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-separate-impl.rs b/src/test/run-pass/structs-enums/class-separate-impl.rs deleted file mode 100644 index 947690b51f4..00000000000 --- a/src/test/run-pass/structs-enums/class-separate-impl.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-str-field.rs b/src/test/run-pass/structs-enums/class-str-field.rs deleted file mode 100644 index a3dc66aab12..00000000000 --- a/src/test/run-pass/structs-enums/class-str-field.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/structs-enums/class-typarams.rs b/src/test/run-pass/structs-enums/class-typarams.rs deleted file mode 100644 index 4b2d4b12ec9..00000000000 --- a/src/test/run-pass/structs-enums/class-typarams.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes-cross-crate.rs b/src/test/run-pass/structs-enums/classes-cross-crate.rs deleted file mode 100644 index ca362c7a7d8..00000000000 --- a/src/test/run-pass/structs-enums/classes-cross-crate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes-self-referential.rs b/src/test/run-pass/structs-enums/classes-self-referential.rs deleted file mode 100644 index 27d6ebf2c2a..00000000000 --- a/src/test/run-pass/structs-enums/classes-self-referential.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes-simple-cross-crate.rs b/src/test/run-pass/structs-enums/classes-simple-cross-crate.rs deleted file mode 100644 index 6ff0970c0f0..00000000000 --- a/src/test/run-pass/structs-enums/classes-simple-cross-crate.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes-simple-method.rs b/src/test/run-pass/structs-enums/classes-simple-method.rs deleted file mode 100644 index f3d98337dba..00000000000 --- a/src/test/run-pass/structs-enums/classes-simple-method.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes-simple.rs b/src/test/run-pass/structs-enums/classes-simple.rs deleted file mode 100644 index 568fbb29f0d..00000000000 --- a/src/test/run-pass/structs-enums/classes-simple.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/structs-enums/classes.rs b/src/test/run-pass/structs-enums/classes.rs deleted file mode 100644 index 51d84b9091d..00000000000 --- a/src/test/run-pass/structs-enums/classes.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/structs-enums/codegen-tag-static-padding.rs b/src/test/run-pass/structs-enums/codegen-tag-static-padding.rs deleted file mode 100644 index 8aa087c018b..00000000000 --- a/src/test/run-pass/structs-enums/codegen-tag-static-padding.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/structs-enums/compare-generic-enums.rs b/src/test/run-pass/structs-enums/compare-generic-enums.rs deleted file mode 100644 index 84f953b1f8e..00000000000 --- a/src/test/run-pass/structs-enums/compare-generic-enums.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/structs-enums/discrim-explicit-23030.rs b/src/test/run-pass/structs-enums/discrim-explicit-23030.rs deleted file mode 100644 index 211ca7e4e8f..00000000000 --- a/src/test/run-pass/structs-enums/discrim-explicit-23030.rs +++ /dev/null @@ -1,147 +0,0 @@ -// 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/src/test/run-pass/structs-enums/empty-struct-braces.rs b/src/test/run-pass/structs-enums/empty-struct-braces.rs deleted file mode 100644 index 0663687c958..00000000000 --- a/src/test/run-pass/structs-enums/empty-struct-braces.rs +++ /dev/null @@ -1,213 +0,0 @@ -// 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/src/test/run-pass/structs-enums/empty-tag.rs b/src/test/run-pass/structs-enums/empty-tag.rs deleted file mode 100644 index 56a438200c0..00000000000 --- a/src/test/run-pass/structs-enums/empty-tag.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![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/src/test/run-pass/structs-enums/enum-alignment.rs b/src/test/run-pass/structs-enums/enum-alignment.rs deleted file mode 100644 index 108dfe2e62d..00000000000 --- a/src/test/run-pass/structs-enums/enum-alignment.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs b/src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs deleted file mode 100644 index e2b2b43dee3..00000000000 --- a/src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-discr.rs b/src/test/run-pass/structs-enums/enum-discr.rs deleted file mode 100644 index bdd6df82d0f..00000000000 --- a/src/test/run-pass/structs-enums/enum-discr.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-discrim-autosizing.rs b/src/test/run-pass/structs-enums/enum-discrim-autosizing.rs deleted file mode 100644 index f68fdda6053..00000000000 --- a/src/test/run-pass/structs-enums/enum-discrim-autosizing.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs b/src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs deleted file mode 100644 index c8b362c9917..00000000000 --- a/src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs +++ /dev/null @@ -1,111 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs b/src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs deleted file mode 100644 index 9c4c61e684b..00000000000 --- a/src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs b/src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs deleted file mode 100644 index f278ae2d0a8..00000000000 --- a/src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-disr-val-pretty.rs b/src/test/run-pass/structs-enums/enum-disr-val-pretty.rs deleted file mode 100644 index ef1333e0eeb..00000000000 --- a/src/test/run-pass/structs-enums/enum-disr-val-pretty.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-export-inheritance.rs b/src/test/run-pass/structs-enums/enum-export-inheritance.rs deleted file mode 100644 index 6a36a004a7c..00000000000 --- a/src/test/run-pass/structs-enums/enum-export-inheritance.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-layout-optimization.rs b/src/test/run-pass/structs-enums/enum-layout-optimization.rs deleted file mode 100644 index 05d297906c3..00000000000 --- a/src/test/run-pass/structs-enums/enum-layout-optimization.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs b/src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs deleted file mode 100644 index 78d8e5e3a5d..00000000000 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs +++ /dev/null @@ -1,171 +0,0 @@ -// 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. - #[allow(deprecated)] - let mut dest: MyEnum = mem::uninitialized(); - 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/src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs b/src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs deleted file mode 100644 index 1209533efda..00000000000 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs +++ /dev/null @@ -1,171 +0,0 @@ -// 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. - #[allow(deprecated)] - let mut dest: MyEnum = mem::uninitialized(); - 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/src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs b/src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs deleted file mode 100644 index 5dd9c1863d6..00000000000 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs +++ /dev/null @@ -1,167 +0,0 @@ -// 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. - #[allow(deprecated)] - let mut dest: MyEnum = mem::uninitialized(); - 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/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs b/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs deleted file mode 100644 index 32fdbf620a9..00000000000 --- a/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs b/src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs deleted file mode 100644 index ae267e7988e..00000000000 --- a/src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs b/src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs deleted file mode 100644 index 77419e1132d..00000000000 --- a/src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-univariant-repr.rs b/src/test/run-pass/structs-enums/enum-univariant-repr.rs deleted file mode 100644 index 1e0f6788778..00000000000 --- a/src/test/run-pass/structs-enums/enum-univariant-repr.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-variants.rs b/src/test/run-pass/structs-enums/enum-variants.rs deleted file mode 100644 index 9ac5aae726a..00000000000 --- a/src/test/run-pass/structs-enums/enum-variants.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/structs-enums/enum-vec-initializer.rs b/src/test/run-pass/structs-enums/enum-vec-initializer.rs deleted file mode 100644 index 42ee8ba971e..00000000000 --- a/src/test/run-pass/structs-enums/enum-vec-initializer.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/structs-enums/export-abstract-tag.rs b/src/test/run-pass/structs-enums/export-abstract-tag.rs deleted file mode 100644 index 76ac73321d3..00000000000 --- a/src/test/run-pass/structs-enums/export-abstract-tag.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/structs-enums/export-tag-variant.rs b/src/test/run-pass/structs-enums/export-tag-variant.rs deleted file mode 100644 index 52e0aba0979..00000000000 --- a/src/test/run-pass/structs-enums/export-tag-variant.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/structs-enums/expr-if-struct.rs b/src/test/run-pass/structs-enums/expr-if-struct.rs deleted file mode 100644 index e62d47c6f5d..00000000000 --- a/src/test/run-pass/structs-enums/expr-if-struct.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/structs-enums/expr-match-struct.rs b/src/test/run-pass/structs-enums/expr-match-struct.rs deleted file mode 100644 index f0e8d897274..00000000000 --- a/src/test/run-pass/structs-enums/expr-match-struct.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/structs-enums/field-destruction-order.rs b/src/test/run-pass/structs-enums/field-destruction-order.rs deleted file mode 100644 index a75a742d90f..00000000000 --- a/src/test/run-pass/structs-enums/field-destruction-order.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/structs-enums/foreign-struct.rs b/src/test/run-pass/structs-enums/foreign-struct.rs deleted file mode 100644 index ce02c8fb5c3..00000000000 --- a/src/test/run-pass/structs-enums/foreign-struct.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/structs-enums/functional-struct-upd.rs b/src/test/run-pass/structs-enums/functional-struct-upd.rs deleted file mode 100644 index 51c6b6d7e4f..00000000000 --- a/src/test/run-pass/structs-enums/functional-struct-upd.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/ivec-tag.rs b/src/test/run-pass/structs-enums/ivec-tag.rs deleted file mode 100644 index c39368a2bb8..00000000000 --- a/src/test/run-pass/structs-enums/ivec-tag.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs b/src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs deleted file mode 100644 index 57be37cdf2b..00000000000 --- a/src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs b/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs deleted file mode 100644 index 30cf645821d..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs b/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs deleted file mode 100644 index f6c395059ed..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs b/src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs deleted file mode 100644 index d2ccadea007..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs b/src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs deleted file mode 100644 index f36ac69dc08..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs b/src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs deleted file mode 100644 index 5e10c3ec1d0..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/structs-enums/namespaced-enums.rs b/src/test/run-pass/structs-enums/namespaced-enums.rs deleted file mode 100644 index 6a2602501a5..00000000000 --- a/src/test/run-pass/structs-enums/namespaced-enums.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/structs-enums/nested-enum-same-names.rs b/src/test/run-pass/structs-enums/nested-enum-same-names.rs deleted file mode 100644 index dece3dcd54b..00000000000 --- a/src/test/run-pass/structs-enums/nested-enum-same-names.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/structs-enums/newtype-struct-drop-run.rs b/src/test/run-pass/structs-enums/newtype-struct-drop-run.rs deleted file mode 100644 index 0754f318701..00000000000 --- a/src/test/run-pass/structs-enums/newtype-struct-drop-run.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs b/src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs deleted file mode 100644 index f73b492dfcf..00000000000 --- a/src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/structs-enums/newtype-struct-xc-2.rs b/src/test/run-pass/structs-enums/newtype-struct-xc-2.rs deleted file mode 100644 index 40837321be2..00000000000 --- a/src/test/run-pass/structs-enums/newtype-struct-xc-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/structs-enums/newtype-struct-xc.rs b/src/test/run-pass/structs-enums/newtype-struct-xc.rs deleted file mode 100644 index 0c6466d97fc..00000000000 --- a/src/test/run-pass/structs-enums/newtype-struct-xc.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/structs-enums/nonzero-enum.rs b/src/test/run-pass/structs-enums/nonzero-enum.rs deleted file mode 100644 index 15b571be563..00000000000 --- a/src/test/run-pass/structs-enums/nonzero-enum.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/structs-enums/numeric-fields.rs b/src/test/run-pass/structs-enums/numeric-fields.rs deleted file mode 100644 index 6ff3afc3870..00000000000 --- a/src/test/run-pass/structs-enums/numeric-fields.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs b/src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs deleted file mode 100644 index e1a865fa503..00000000000 --- a/src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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/src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs b/src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs deleted file mode 100644 index 1fc52ead48e..00000000000 --- a/src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/structs-enums/rec-align-u32.rs b/src/test/run-pass/structs-enums/rec-align-u32.rs deleted file mode 100644 index 889294daa34..00000000000 --- a/src/test/run-pass/structs-enums/rec-align-u32.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/structs-enums/rec-align-u64.rs b/src/test/run-pass/structs-enums/rec-align-u64.rs deleted file mode 100644 index c4e9e9ea5ee..00000000000 --- a/src/test/run-pass/structs-enums/rec-align-u64.rs +++ /dev/null @@ -1,101 +0,0 @@ -// 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"))] -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 { - #[cfg(target_arch = "x86")] - pub mod m { - pub fn align() -> usize { 8 } - pub fn size() -> usize { 16 } - } - - #[cfg(target_arch = "x86_64")] - 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/src/test/run-pass/structs-enums/rec-auto.rs b/src/test/run-pass/structs-enums/rec-auto.rs deleted file mode 100644 index c2ef13ede4c..00000000000 --- a/src/test/run-pass/structs-enums/rec-auto.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/structs-enums/rec-extend.rs b/src/test/run-pass/structs-enums/rec-extend.rs deleted file mode 100644 index 4c91cd1850e..00000000000 --- a/src/test/run-pass/structs-enums/rec-extend.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/structs-enums/rec-tup.rs b/src/test/run-pass/structs-enums/rec-tup.rs deleted file mode 100644 index b85d28fdf03..00000000000 --- a/src/test/run-pass/structs-enums/rec-tup.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/structs-enums/rec.rs b/src/test/run-pass/structs-enums/rec.rs deleted file mode 100644 index 82c84ebd6ff..00000000000 --- a/src/test/run-pass/structs-enums/rec.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/structs-enums/record-pat.rs b/src/test/run-pass/structs-enums/record-pat.rs deleted file mode 100644 index 1acaf2a32c2..00000000000 --- a/src/test/run-pass/structs-enums/record-pat.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/structs-enums/resource-in-struct.rs b/src/test/run-pass/structs-enums/resource-in-struct.rs deleted file mode 100644 index 35a4b14bc3f..00000000000 --- a/src/test/run-pass/structs-enums/resource-in-struct.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/structs-enums/simple-generic-tag.rs b/src/test/run-pass/structs-enums/simple-generic-tag.rs deleted file mode 100644 index dbd2834d468..00000000000 --- a/src/test/run-pass/structs-enums/simple-generic-tag.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - - -// pretty-expanded FIXME #23616 - -enum clam { a(T), } - -pub fn main() { } diff --git a/src/test/run-pass/structs-enums/simple-match-generic-tag.rs b/src/test/run-pass/structs-enums/simple-match-generic-tag.rs deleted file mode 100644 index 762fd49ad24..00000000000 --- a/src/test/run-pass/structs-enums/simple-match-generic-tag.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/structs-enums/small-enum-range-edge.rs b/src/test/run-pass/structs-enums/small-enum-range-edge.rs deleted file mode 100644 index 30612947963..00000000000 --- a/src/test/run-pass/structs-enums/small-enum-range-edge.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/structs-enums/small-enums-with-fields.rs b/src/test/run-pass/structs-enums/small-enums-with-fields.rs deleted file mode 100644 index 565ec1bd45d..00000000000 --- a/src/test/run-pass/structs-enums/small-enums-with-fields.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-aliases-xcrate.rs b/src/test/run-pass/structs-enums/struct-aliases-xcrate.rs deleted file mode 100644 index ffe7b22f809..00000000000 --- a/src/test/run-pass/structs-enums/struct-aliases-xcrate.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-aliases.rs b/src/test/run-pass/structs-enums/struct-aliases.rs deleted file mode 100644 index b7aeed7bc39..00000000000 --- a/src/test/run-pass/structs-enums/struct-aliases.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs b/src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs deleted file mode 100644 index 19e0a0bbdd2..00000000000 --- a/src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-field-shorthand.rs b/src/test/run-pass/structs-enums/struct-field-shorthand.rs deleted file mode 100644 index ed650c68364..00000000000 --- a/src/test/run-pass/structs-enums/struct-field-shorthand.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-like-variant-construct.rs b/src/test/run-pass/structs-enums/struct-like-variant-construct.rs deleted file mode 100644 index 60fc7ce394c..00000000000 --- a/src/test/run-pass/structs-enums/struct-like-variant-construct.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-like-variant-match.rs b/src/test/run-pass/structs-enums/struct-like-variant-match.rs deleted file mode 100644 index ade1a697037..00000000000 --- a/src/test/run-pass/structs-enums/struct-like-variant-match.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs b/src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs deleted file mode 100644 index f19604e951c..00000000000 --- a/src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-literal-dtor.rs b/src/test/run-pass/structs-enums/struct-literal-dtor.rs deleted file mode 100644 index 6d1b1dfb9b6..00000000000 --- a/src/test/run-pass/structs-enums/struct-literal-dtor.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-new-as-field-name.rs b/src/test/run-pass/structs-enums/struct-new-as-field-name.rs deleted file mode 100644 index 641fc3c5867..00000000000 --- a/src/test/run-pass/structs-enums/struct-new-as-field-name.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -struct Foo { - new: isize, -} - -pub fn main() { - let foo = Foo{ new: 3 }; - assert_eq!(foo.new, 3); -} diff --git a/src/test/run-pass/structs-enums/struct-order-of-eval-1.rs b/src/test/run-pass/structs-enums/struct-order-of-eval-1.rs deleted file mode 100644 index f3fe9953856..00000000000 --- a/src/test/run-pass/structs-enums/struct-order-of-eval-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-order-of-eval-2.rs b/src/test/run-pass/structs-enums/struct-order-of-eval-2.rs deleted file mode 100644 index a4e0edc97c6..00000000000 --- a/src/test/run-pass/structs-enums/struct-order-of-eval-2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-order-of-eval-3.rs b/src/test/run-pass/structs-enums/struct-order-of-eval-3.rs deleted file mode 100644 index 60887f8d05a..00000000000 --- a/src/test/run-pass/structs-enums/struct-order-of-eval-3.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-order-of-eval-4.rs b/src/test/run-pass/structs-enums/struct-order-of-eval-4.rs deleted file mode 100644 index 547df631846..00000000000 --- a/src/test/run-pass/structs-enums/struct-order-of-eval-4.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-partial-move-1.rs b/src/test/run-pass/structs-enums/struct-partial-move-1.rs deleted file mode 100644 index c1570159388..00000000000 --- a/src/test/run-pass/structs-enums/struct-partial-move-1.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-partial-move-2.rs b/src/test/run-pass/structs-enums/struct-partial-move-2.rs deleted file mode 100644 index 4315e5c29f3..00000000000 --- a/src/test/run-pass/structs-enums/struct-partial-move-2.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-path-associated-type.rs b/src/test/run-pass/structs-enums/struct-path-associated-type.rs deleted file mode 100644 index 2235dfe4b84..00000000000 --- a/src/test/run-pass/structs-enums/struct-path-associated-type.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-path-self.rs b/src/test/run-pass/structs-enums/struct-path-self.rs deleted file mode 100644 index e7a59858f57..00000000000 --- a/src/test/run-pass/structs-enums/struct-path-self.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-pattern-matching.rs b/src/test/run-pass/structs-enums/struct-pattern-matching.rs deleted file mode 100644 index 89361bf2455..00000000000 --- a/src/test/run-pass/structs-enums/struct-pattern-matching.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct-return.rs b/src/test/run-pass/structs-enums/struct-return.rs deleted file mode 100644 index 5930fc4acbb..00000000000 --- a/src/test/run-pass/structs-enums/struct-return.rs +++ /dev/null @@ -1,64 +0,0 @@ -// 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 } - -mod rustrt { - use super::{Floats, Quad}; - - #[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; - } -} - -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() { -} - -pub fn main() { - test1(); - test2(); -} diff --git a/src/test/run-pass/structs-enums/struct-variant-field-visibility.rs b/src/test/run-pass/structs-enums/struct-variant-field-visibility.rs deleted file mode 100644 index 7896c829a6e..00000000000 --- a/src/test/run-pass/structs-enums/struct-variant-field-visibility.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct_variant_xc.rs b/src/test/run-pass/structs-enums/struct_variant_xc.rs deleted file mode 100644 index 9c8d1a69a3e..00000000000 --- a/src/test/run-pass/structs-enums/struct_variant_xc.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/structs-enums/struct_variant_xc_match.rs b/src/test/run-pass/structs-enums/struct_variant_xc_match.rs deleted file mode 100644 index 5358d13faa9..00000000000 --- a/src/test/run-pass/structs-enums/struct_variant_xc_match.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-align-dyn-u64.rs b/src/test/run-pass/structs-enums/tag-align-dyn-u64.rs deleted file mode 100644 index 3f7a5e3e511..00000000000 --- a/src/test/run-pass/structs-enums/tag-align-dyn-u64.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-align-dyn-variants.rs b/src/test/run-pass/structs-enums/tag-align-dyn-variants.rs deleted file mode 100644 index 4d075b04c97..00000000000 --- a/src/test/run-pass/structs-enums/tag-align-dyn-variants.rs +++ /dev/null @@ -1,67 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-align-shape.rs b/src/test/run-pass/structs-enums/tag-align-shape.rs deleted file mode 100644 index 87282ddbcca..00000000000 --- a/src/test/run-pass/structs-enums/tag-align-shape.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-align-u64.rs b/src/test/run-pass/structs-enums/tag-align-u64.rs deleted file mode 100644 index 684b27cd030..00000000000 --- a/src/test/run-pass/structs-enums/tag-align-u64.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-disr-val-shape.rs b/src/test/run-pass/structs-enums/tag-disr-val-shape.rs deleted file mode 100644 index 51052626c30..00000000000 --- a/src/test/run-pass/structs-enums/tag-disr-val-shape.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-exports.rs b/src/test/run-pass/structs-enums/tag-exports.rs deleted file mode 100644 index 1bcb7d35da3..00000000000 --- a/src/test/run-pass/structs-enums/tag-exports.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-in-block.rs b/src/test/run-pass/structs-enums/tag-in-block.rs deleted file mode 100644 index 03d4dd9b0ab..00000000000 --- a/src/test/run-pass/structs-enums/tag-in-block.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs b/src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs deleted file mode 100644 index 3f59db38310..00000000000 --- a/src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag-variant-disr-val.rs b/src/test/run-pass/structs-enums/tag-variant-disr-val.rs deleted file mode 100644 index 297d85c5886..00000000000 --- a/src/test/run-pass/structs-enums/tag-variant-disr-val.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tag.rs b/src/test/run-pass/structs-enums/tag.rs deleted file mode 100644 index 5fcd64b7cd1..00000000000 --- a/src/test/run-pass/structs-enums/tag.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tuple-struct-construct.rs b/src/test/run-pass/structs-enums/tuple-struct-construct.rs deleted file mode 100644 index 972fc9dc04a..00000000000 --- a/src/test/run-pass/structs-enums/tuple-struct-construct.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#[derive(Debug)] -struct Foo(isize, isize); - -pub fn main() { - let x = Foo(1, 2); - println!("{:?}", x); -} diff --git a/src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs b/src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs deleted file mode 100644 index 23f06516323..00000000000 --- a/src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tuple-struct-destructuring.rs b/src/test/run-pass/structs-enums/tuple-struct-destructuring.rs deleted file mode 100644 index dff87ead033..00000000000 --- a/src/test/run-pass/structs-enums/tuple-struct-destructuring.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tuple-struct-matching.rs b/src/test/run-pass/structs-enums/tuple-struct-matching.rs deleted file mode 100644 index 432be1d1f7a..00000000000 --- a/src/test/run-pass/structs-enums/tuple-struct-matching.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/structs-enums/tuple-struct-trivial.rs b/src/test/run-pass/structs-enums/tuple-struct-trivial.rs deleted file mode 100644 index c8651fd29de..00000000000 --- a/src/test/run-pass/structs-enums/tuple-struct-trivial.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -struct Foo(isize, isize, isize); - -pub fn main() { -} diff --git a/src/test/run-pass/structs-enums/uninstantiable-struct.rs b/src/test/run-pass/structs-enums/uninstantiable-struct.rs deleted file mode 100644 index b1ef525614e..00000000000 --- a/src/test/run-pass/structs-enums/uninstantiable-struct.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -pub struct Z(&'static Z); - -pub fn main() {} diff --git a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs b/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs deleted file mode 100644 index 980fd97e2c6..00000000000 --- a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/structs-enums/unit-like-struct.rs b/src/test/run-pass/structs-enums/unit-like-struct.rs deleted file mode 100644 index 636ec992667..00000000000 --- a/src/test/run-pass/structs-enums/unit-like-struct.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -struct Foo; - -pub fn main() { - let x: Foo = Foo; - match x { - Foo => { println!("hi"); } - } -} diff --git a/src/test/run-pass/structs-enums/variant-structs-trivial.rs b/src/test/run-pass/structs-enums/variant-structs-trivial.rs deleted file mode 100644 index 31fa610a69d..00000000000 --- a/src/test/run-pass/structs-enums/variant-structs-trivial.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -enum Foo { - Bar { x: isize }, - Baz { y: isize } -} - -pub fn main() { } diff --git a/src/test/run-pass/structured-compare.rs b/src/test/run-pass/structured-compare.rs deleted file mode 100644 index 63d30c4da89..00000000000 --- a/src/test/run-pass/structured-compare.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/super-fast-paren-parsing.rs b/src/test/run-pass/super-fast-paren-parsing.rs deleted file mode 100644 index 60c8db53a8c..00000000000 --- a/src/test/run-pass/super-fast-paren-parsing.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/super.rs b/src/test/run-pass/super.rs deleted file mode 100644 index 86c720288c3..00000000000 --- a/src/test/run-pass/super.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/supported-cast.rs b/src/test/run-pass/supported-cast.rs deleted file mode 100644 index ff41ce6c79a..00000000000 --- a/src/test/run-pass/supported-cast.rs +++ /dev/null @@ -1,206 +0,0 @@ -// 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/src/test/run-pass/svh-add-nothing.rs b/src/test/run-pass/svh-add-nothing.rs deleted file mode 100644 index d7d037f0b32..00000000000 --- a/src/test/run-pass/svh-add-nothing.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/swap-1.rs b/src/test/run-pass/swap-1.rs deleted file mode 100644 index d87114748dd..00000000000 --- a/src/test/run-pass/swap-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/swap-2.rs b/src/test/run-pass/swap-2.rs deleted file mode 100644 index c8f298ec0e5..00000000000 --- a/src/test/run-pass/swap-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -use std::mem::swap; - -pub fn main() { - let mut a: Vec = vec![0, 1, 2, 3, 4, 5, 6]; - a.swap(2, 4); - assert_eq!(a[2], 4); - assert_eq!(a[4], 2); - let mut n = 42; - swap(&mut n, &mut a[0]); - assert_eq!(a[0], 42); - assert_eq!(n, 0); -} diff --git a/src/test/run-pass/swap-overlapping.rs b/src/test/run-pass/swap-overlapping.rs deleted file mode 100644 index 85b357e0c02..00000000000 --- a/src/test/run-pass/swap-overlapping.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/tail-call-arg-leak.rs b/src/test/run-pass/tail-call-arg-leak.rs deleted file mode 100644 index a60944b632d..00000000000 --- a/src/test/run-pass/tail-call-arg-leak.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/tail-cps.rs b/src/test/run-pass/tail-cps.rs deleted file mode 100644 index f186683ea66..00000000000 --- a/src/test/run-pass/tail-cps.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/tail-direct.rs b/src/test/run-pass/tail-direct.rs deleted file mode 100644 index c67c5b7a555..00000000000 --- a/src/test/run-pass/tail-direct.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs deleted file mode 100644 index 1f1948fa8fa..00000000000 --- a/src/test/run-pass/tcp-stress.rs +++ /dev/null @@ -1,66 +0,0 @@ -// 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) -// ignore-sgx no thread sleep support - -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/src/test/run-pass/terminate-in-initializer.rs b/src/test/run-pass/terminate-in-initializer.rs deleted file mode 100644 index c9cb932e62a..00000000000 --- a/src/test/run-pass/terminate-in-initializer.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/test-allow-dead-extern-static-no-warning.rs b/src/test/run-pass/test-allow-dead-extern-static-no-warning.rs deleted file mode 100644 index 2583e431ec1..00000000000 --- a/src/test/run-pass/test-allow-dead-extern-static-no-warning.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// compile-flags: --test - -#![deny(dead_code)] - -extern "C" { - #[allow(dead_code)] - static Qt: u64; -} - -fn main() {} diff --git a/src/test/run-pass/test-allow-fail-attr.rs b/src/test/run-pass/test-allow-fail-attr.rs deleted file mode 100644 index 1a478460efc..00000000000 --- a/src/test/run-pass/test-allow-fail-attr.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// ignore-wasm32-bare compiled with panic=abort by default -// compile-flags: --test -#![feature(allow_fail)] - -#[test] -#[allow_fail] -fn test1() { - panic!(); -} - -#[test] -#[allow_fail] -fn test2() { - assert!(true); -} diff --git a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs deleted file mode 100644 index ff62d84925f..00000000000 --- a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/test-main-not-dead-attr.rs b/src/test/run-pass/test-main-not-dead-attr.rs deleted file mode 100644 index 628b1896ace..00000000000 --- a/src/test/run-pass/test-main-not-dead-attr.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// compile-flags: --test - -#![feature(main)] - -#![deny(dead_code)] - -#[main] -fn foo() { panic!(); } diff --git a/src/test/run-pass/test-main-not-dead.rs b/src/test/run-pass/test-main-not-dead.rs deleted file mode 100644 index 30a9c85e3d2..00000000000 --- a/src/test/run-pass/test-main-not-dead.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// compile-flags: --test - -#![deny(dead_code)] - -fn main() { panic!(); } diff --git a/src/test/run-pass/test-runner-hides-buried-main.rs b/src/test/run-pass/test-runner-hides-buried-main.rs deleted file mode 100644 index 917c09801e1..00000000000 --- a/src/test/run-pass/test-runner-hides-buried-main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -// compile-flags: --test - -#![feature(main)] - -#![allow(dead_code)] - -mod a { - fn b() { - || { - #[main] - fn c() { panic!(); } - }; - } -} diff --git a/src/test/run-pass/test-runner-hides-main.rs b/src/test/run-pass/test-runner-hides-main.rs deleted file mode 100644 index 0de1d64f0fc..00000000000 --- a/src/test/run-pass/test-runner-hides-main.rs +++ /dev/null @@ -1,5 +0,0 @@ -// 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/src/test/run-pass/test-runner-hides-start.rs b/src/test/run-pass/test-runner-hides-start.rs deleted file mode 100644 index 56212bb6f4b..00000000000 --- a/src/test/run-pass/test-runner-hides-start.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// compile-flags: --test - -#![feature(start)] - -#[start] -fn start(_: isize, _: *const *const u8) -> isize { panic!(); } diff --git a/src/test/run-pass/test-should-fail-good-message.rs b/src/test/run-pass/test-should-fail-good-message.rs deleted file mode 100644 index 9fa759f9eb4..00000000000 --- a/src/test/run-pass/test-should-fail-good-message.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/test-vs-cfg-test.rs b/src/test/run-pass/test-vs-cfg-test.rs deleted file mode 100644 index cd1cd33c284..00000000000 --- a/src/test/run-pass/test-vs-cfg-test.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// compile-flags: --cfg test - -// Make sure `--cfg test` does not inject test harness - -#[test] -fn test() { panic!(); } - -fn main() {} diff --git a/src/test/run-pass/thin-lto-global-allocator.rs b/src/test/run-pass/thin-lto-global-allocator.rs deleted file mode 100644 index e00c5caf97c..00000000000 --- a/src/test/run-pass/thin-lto-global-allocator.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/thinlto/all-crates.rs b/src/test/run-pass/thinlto/all-crates.rs deleted file mode 100644 index e910b2a9f96..00000000000 --- a/src/test/run-pass/thinlto/all-crates.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -// compile-flags: -Clto=thin -// no-prefer-dynamic - -fn main() { - println!("hello!"); -} diff --git a/src/test/run-pass/thinlto/auxiliary/dylib.rs b/src/test/run-pass/thinlto/auxiliary/dylib.rs deleted file mode 100644 index e8b7f8f9f47..00000000000 --- a/src/test/run-pass/thinlto/auxiliary/dylib.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags: -Z thinlto -C codegen-units=8 - -#[inline] -pub fn foo(b: u8) { - b.to_string(); -} diff --git a/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs b/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs deleted file mode 100644 index 933af050a6a..00000000000 --- a/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs deleted file mode 100644 index 5fd3f1996dd..00000000000 --- a/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs +++ /dev/null @@ -1,7 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -pub fn bar() -> u32 { - 3 -} diff --git a/src/test/run-pass/thinlto/dylib-works.rs b/src/test/run-pass/thinlto/dylib-works.rs deleted file mode 100644 index 9e0782b590e..00000000000 --- a/src/test/run-pass/thinlto/dylib-works.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -// aux-build:dylib.rs - -extern crate dylib; - -fn main() { - dylib::foo(1); -} diff --git a/src/test/run-pass/thinlto/msvc-imp-present.rs b/src/test/run-pass/thinlto/msvc-imp-present.rs deleted file mode 100644 index 5498afb2937..00000000000 --- a/src/test/run-pass/thinlto/msvc-imp-present.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/thinlto/thin-lto-inlines.rs b/src/test/run-pass/thinlto/thin-lto-inlines.rs deleted file mode 100644 index dca7918077e..00000000000 --- a/src/test/run-pass/thinlto/thin-lto-inlines.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs deleted file mode 100644 index 1eb29657c70..00000000000 --- a/src/test/run-pass/thinlto/thin-lto-inlines2.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/thinlto/weak-works.rs b/src/test/run-pass/thinlto/weak-works.rs deleted file mode 100644 index 163a3870248..00000000000 --- a/src/test/run-pass/thinlto/weak-works.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/thread-local-not-in-prelude.rs b/src/test/run-pass/thread-local-not-in-prelude.rs deleted file mode 100644 index 03974982625..00000000000 --- a/src/test/run-pass/thread-local-not-in-prelude.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass - -#![no_std] - -extern crate std; - -std::thread_local!(static A: usize = 30); - -fn main() { -} diff --git a/src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs b/src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs deleted file mode 100644 index b237b1c480e..00000000000 --- a/src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![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/src/test/run-pass/threads-sendsync/comm.rs b/src/test/run-pass/threads-sendsync/comm.rs deleted file mode 100644 index aa86e174d44..00000000000 --- a/src/test/run-pass/threads-sendsync/comm.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs b/src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs deleted file mode 100644 index dbe46555101..00000000000 --- a/src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/send-resource.rs b/src/test/run-pass/threads-sendsync/send-resource.rs deleted file mode 100644 index 023a84d6b6e..00000000000 --- a/src/test/run-pass/threads-sendsync/send-resource.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/send-type-inference.rs b/src/test/run-pass/threads-sendsync/send-type-inference.rs deleted file mode 100644 index 0d9af7512b4..00000000000 --- a/src/test/run-pass/threads-sendsync/send-type-inference.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/send_str_hashmap.rs b/src/test/run-pass/threads-sendsync/send_str_hashmap.rs deleted file mode 100644 index 7d4cca8ad74..00000000000 --- a/src/test/run-pass/threads-sendsync/send_str_hashmap.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/send_str_treemap.rs b/src/test/run-pass/threads-sendsync/send_str_treemap.rs deleted file mode 100644 index 4d463174590..00000000000 --- a/src/test/run-pass/threads-sendsync/send_str_treemap.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sendable-class.rs b/src/test/run-pass/threads-sendsync/sendable-class.rs deleted file mode 100644 index 7facf245bde..00000000000 --- a/src/test/run-pass/threads-sendsync/sendable-class.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs b/src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs deleted file mode 100644 index 62807d8941a..00000000000 --- a/src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs deleted file mode 100644 index 8c40b2a5f11..00000000000 --- a/src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/spawn-fn.rs b/src/test/run-pass/threads-sendsync/spawn-fn.rs deleted file mode 100644 index 1243bb2579f..00000000000 --- a/src/test/run-pass/threads-sendsync/spawn-fn.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/spawn-types.rs b/src/test/run-pass/threads-sendsync/spawn-types.rs deleted file mode 100644 index 1bead6e1bb1..00000000000 --- a/src/test/run-pass/threads-sendsync/spawn-types.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/spawn.rs b/src/test/run-pass/threads-sendsync/spawn.rs deleted file mode 100644 index b1dcc9417fb..00000000000 --- a/src/test/run-pass/threads-sendsync/spawn.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/spawn2.rs b/src/test/run-pass/threads-sendsync/spawn2.rs deleted file mode 100644 index 83e066aef96..00000000000 --- a/src/test/run-pass/threads-sendsync/spawn2.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/spawning-with-debug.rs b/src/test/run-pass/threads-sendsync/spawning-with-debug.rs deleted file mode 100644 index 388d62aa710..00000000000 --- a/src/test/run-pass/threads-sendsync/spawning-with-debug.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass -#![allow(unused_must_use)] -#![allow(unused_mut)] -// ignore-windows -// exec-env:RUSTC_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/src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs b/src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs deleted file mode 100644 index bc64c816243..00000000000 --- a/src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sync-send-atomics.rs b/src/test/run-pass/threads-sendsync/sync-send-atomics.rs deleted file mode 100644 index 0466f4f0e9d..00000000000 --- a/src/test/run-pass/threads-sendsync/sync-send-atomics.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sync-send-in-std.rs b/src/test/run-pass/threads-sendsync/sync-send-in-std.rs deleted file mode 100644 index 15e10dc250f..00000000000 --- a/src/test/run-pass/threads-sendsync/sync-send-in-std.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs deleted file mode 100644 index fd53bb607f7..00000000000 --- a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs +++ /dev/null @@ -1,71 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs deleted file mode 100644 index 44beb9dc1e5..00000000000 --- a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs +++ /dev/null @@ -1,104 +0,0 @@ -// 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!(once(1)); - - // for option.rs - // FIXME - - // for result.rs - // FIXME - - // for slice.rs - // FIXME - - // for str/mod.rs - // FIXME -} diff --git a/src/test/run-pass/threads-sendsync/task-comm-0.rs b/src/test/run-pass/threads-sendsync/task-comm-0.rs deleted file mode 100644 index 2b9a50e4d41..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-0.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-1.rs b/src/test/run-pass/threads-sendsync/task-comm-1.rs deleted file mode 100644 index 68ca62909bf..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-1.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-10.rs b/src/test/run-pass/threads-sendsync/task-comm-10.rs deleted file mode 100644 index 4cac0dc90cf..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-10.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-11.rs b/src/test/run-pass/threads-sendsync/task-comm-11.rs deleted file mode 100644 index 8541e143fb9..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-11.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-12.rs b/src/test/run-pass/threads-sendsync/task-comm-12.rs deleted file mode 100644 index 613a5cee58b..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-12.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-13.rs b/src/test/run-pass/threads-sendsync/task-comm-13.rs deleted file mode 100644 index 327eaaf8fa1..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-13.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-14.rs b/src/test/run-pass/threads-sendsync/task-comm-14.rs deleted file mode 100644 index 88d6b090268..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-14.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-15.rs b/src/test/run-pass/threads-sendsync/task-comm-15.rs deleted file mode 100644 index adb14abdce9..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-15.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-16.rs b/src/test/run-pass/threads-sendsync/task-comm-16.rs deleted file mode 100644 index d808fd9aceb..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-16.rs +++ /dev/null @@ -1,111 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-17.rs b/src/test/run-pass/threads-sendsync/task-comm-17.rs deleted file mode 100644 index 72249787093..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-17.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-3.rs b/src/test/run-pass/threads-sendsync/task-comm-3.rs deleted file mode 100644 index 570ae0a82ff..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-3.rs +++ /dev/null @@ -1,63 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-4.rs b/src/test/run-pass/threads-sendsync/task-comm-4.rs deleted file mode 100644 index b259d69d15d..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-4.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-5.rs b/src/test/run-pass/threads-sendsync/task-comm-5.rs deleted file mode 100644 index cdedf034ac3..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-5.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-6.rs b/src/test/run-pass/threads-sendsync/task-comm-6.rs deleted file mode 100644 index 990205ad334..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-6.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-7.rs b/src/test/run-pass/threads-sendsync/task-comm-7.rs deleted file mode 100644 index 0b9673e0033..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-7.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-9.rs b/src/test/run-pass/threads-sendsync/task-comm-9.rs deleted file mode 100644 index 5ed33012100..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-9.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs b/src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs deleted file mode 100644 index a93ddff43dc..00000000000 --- a/src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-life-0.rs b/src/test/run-pass/threads-sendsync/task-life-0.rs deleted file mode 100644 index 785cff9a0f3..00000000000 --- a/src/test/run-pass/threads-sendsync/task-life-0.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs b/src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs deleted file mode 100644 index 458f5653885..00000000000 --- a/src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/task-stderr.rs b/src/test/run-pass/threads-sendsync/task-stderr.rs deleted file mode 100644 index d474084bf20..00000000000 --- a/src/test/run-pass/threads-sendsync/task-stderr.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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(()) } -} - -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/src/test/run-pass/threads-sendsync/thread-local-extern-static.rs b/src/test/run-pass/threads-sendsync/thread-local-extern-static.rs deleted file mode 100644 index e10f5174b12..00000000000 --- a/src/test/run-pass/threads-sendsync/thread-local-extern-static.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/thread-local-syntax.rs b/src/test/run-pass/threads-sendsync/thread-local-syntax.rs deleted file mode 100644 index 2f4805e4731..00000000000 --- a/src/test/run-pass/threads-sendsync/thread-local-syntax.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/threads.rs b/src/test/run-pass/threads-sendsync/threads.rs deleted file mode 100644 index e3da83aa12b..00000000000 --- a/src/test/run-pass/threads-sendsync/threads.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs deleted file mode 100644 index 8baef433410..00000000000 --- a/src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/tls-init-on-init.rs b/src/test/run-pass/threads-sendsync/tls-init-on-init.rs deleted file mode 100644 index 193c1815105..00000000000 --- a/src/test/run-pass/threads-sendsync/tls-init-on-init.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/threads-sendsync/tls-try-with.rs b/src/test/run-pass/threads-sendsync/tls-try-with.rs deleted file mode 100644 index f36ab4e4f9c..00000000000 --- a/src/test/run-pass/threads-sendsync/tls-try-with.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/tool_attributes.rs b/src/test/run-pass/tool_attributes.rs deleted file mode 100644 index be4a10c0ee9..00000000000 --- a/src/test/run-pass/tool_attributes.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/tool_lints_2018_preview.rs b/src/test/run-pass/tool_lints_2018_preview.rs deleted file mode 100644 index 190f0b99dc8..00000000000 --- a/src/test/run-pass/tool_lints_2018_preview.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -#![feature(rust_2018_preview)] -#![deny(unknown_lints)] - -#[allow(clippy::almost_swapped)] -fn main() {} diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs deleted file mode 100644 index f34e6b7606d..00000000000 --- a/src/test/run-pass/trailing-comma.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(slice_patterns)] - -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/src/test/run-pass/traits/anon-trait-static-method.rs b/src/test/run-pass/traits/anon-trait-static-method.rs deleted file mode 100644 index ede01afae02..00000000000 --- a/src/test/run-pass/traits/anon-trait-static-method.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/traits/anon_trait_static_method_exe.rs b/src/test/run-pass/traits/anon_trait_static_method_exe.rs deleted file mode 100644 index b4930295499..00000000000 --- a/src/test/run-pass/traits/anon_trait_static_method_exe.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/traits/assignability-trait.rs b/src/test/run-pass/traits/assignability-trait.rs deleted file mode 100644 index a8547c1d271..00000000000 --- a/src/test/run-pass/traits/assignability-trait.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs b/src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs deleted file mode 100644 index cc8f9dc5190..00000000000 --- a/src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/traits/augmented-assignments-trait.rs b/src/test/run-pass/traits/augmented-assignments-trait.rs deleted file mode 100644 index 8c418daffdf..00000000000 --- a/src/test/run-pass/traits/augmented-assignments-trait.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/traits/auto-traits.rs b/src/test/run-pass/traits/auto-traits.rs deleted file mode 100644 index c495b97b25b..00000000000 --- a/src/test/run-pass/traits/auto-traits.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -#![allow(unused_doc_comments)] -#![feature(optin_builtin_traits)] - -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/src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs b/src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs deleted file mode 100644 index dceec7e3ec1..00000000000 --- a/src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct Foo { - pub x: isize -} - -impl Foo { - pub fn new() -> Foo { - Foo { x: 3 } - } -} diff --git a/src/test/run-pass/traits/auxiliary/go_trait.rs b/src/test/run-pass/traits/auxiliary/go_trait.rs deleted file mode 100644 index aa0ec22896d..00000000000 --- a/src/test/run-pass/traits/auxiliary/go_trait.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![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/src/test/run-pass/traits/auxiliary/trait_alias.rs b/src/test/run-pass/traits/auxiliary/trait_alias.rs deleted file mode 100644 index 9e412215512..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_alias.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![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/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs b/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs deleted file mode 100644 index 0fb26af80c7..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs +++ /dev/null @@ -1,40 +0,0 @@ -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/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs b/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs deleted file mode 100644 index 15480132a23..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs b/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs deleted file mode 100644 index e9327676dc6..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs deleted file mode 100644 index 9af26cb2e2b..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs +++ /dev/null @@ -1,7 +0,0 @@ -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/src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs deleted file mode 100644 index a2570441226..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs +++ /dev/null @@ -1,38 +0,0 @@ -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/src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs b/src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs deleted file mode 100644 index b76c52e62a9..00000000000 --- a/src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/src/test/run-pass/traits/auxiliary/traitimpl.rs b/src/test/run-pass/traits/auxiliary/traitimpl.rs deleted file mode 100644 index fda5314cdbf..00000000000 --- a/src/test/run-pass/traits/auxiliary/traitimpl.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Test inherent trait impls work cross-crait. - -pub trait Bar<'a> : 'a {} - -impl<'a> Bar<'a> { - pub fn bar(&self) {} -} diff --git a/src/test/run-pass/traits/cycle-trait-type-trait.rs b/src/test/run-pass/traits/cycle-trait-type-trait.rs deleted file mode 100644 index c62d01403c7..00000000000 --- a/src/test/run-pass/traits/cycle-trait-type-trait.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/traits/default-method-supertrait-vtable.rs b/src/test/run-pass/traits/default-method-supertrait-vtable.rs deleted file mode 100644 index 939ad51355e..00000000000 --- a/src/test/run-pass/traits/default-method-supertrait-vtable.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/traits/dyn-trait.rs b/src/test/run-pass/traits/dyn-trait.rs deleted file mode 100644 index e1c1a8de55a..00000000000 --- a/src/test/run-pass/traits/dyn-trait.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/traits/fmt-pointer-trait.rs b/src/test/run-pass/traits/fmt-pointer-trait.rs deleted file mode 100644 index b7876b9bd51..00000000000 --- a/src/test/run-pass/traits/fmt-pointer-trait.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/traits/impl-implicit-trait.rs b/src/test/run-pass/traits/impl-implicit-trait.rs deleted file mode 100644 index fac2bcce248..00000000000 --- a/src/test/run-pass/traits/impl-implicit-trait.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs b/src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs deleted file mode 100644 index 82760788897..00000000000 --- a/src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs b/src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs deleted file mode 100644 index ed258dbb24c..00000000000 --- a/src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/inherent-trait-method-order.rs b/src/test/run-pass/traits/inherent-trait-method-order.rs deleted file mode 100644 index f632ae8a9ac..00000000000 --- a/src/test/run-pass/traits/inherent-trait-method-order.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/traits/kindck-owned-trait-contains-1.rs b/src/test/run-pass/traits/kindck-owned-trait-contains-1.rs deleted file mode 100644 index 23b91f924b5..00000000000 --- a/src/test/run-pass/traits/kindck-owned-trait-contains-1.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/multiple-trait-bounds.rs b/src/test/run-pass/traits/multiple-trait-bounds.rs deleted file mode 100644 index 868b334070b..00000000000 --- a/src/test/run-pass/traits/multiple-trait-bounds.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn f(_: T) { -} - -pub fn main() { - f(3); -} diff --git a/src/test/run-pass/traits/object-one-type-two-traits.rs b/src/test/run-pass/traits/object-one-type-two-traits.rs deleted file mode 100644 index b92a2ab7b4b..00000000000 --- a/src/test/run-pass/traits/object-one-type-two-traits.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs b/src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs deleted file mode 100644 index bc8dc8dbd05..00000000000 --- a/src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![feature(overlapping_marker_traits)] -#![feature(optin_builtin_traits)] - -// Overlapping negative impls for `MyStruct` are permitted: -struct MyStruct; -impl !Send for MyStruct {} -impl !Send for MyStruct {} - -fn main() { -} diff --git a/src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs b/src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs deleted file mode 100644 index 59ec9d5689d..00000000000 --- a/src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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(overlapping_marker_traits)] -#![feature(optin_builtin_traits)] - -use std::fmt::{Debug, Display}; - -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/src/test/run-pass/traits/parameterized-trait-with-bounds.rs b/src/test/run-pass/traits/parameterized-trait-with-bounds.rs deleted file mode 100644 index 832d4f6c89f..00000000000 --- a/src/test/run-pass/traits/parameterized-trait-with-bounds.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/traits/principal-less-trait-objects.rs b/src/test/run-pass/traits/principal-less-trait-objects.rs deleted file mode 100644 index 82624650a54..00000000000 --- a/src/test/run-pass/traits/principal-less-trait-objects.rs +++ /dev/null @@ -1,42 +0,0 @@ -// 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/src/test/run-pass/traits/supertrait-default-generics.rs b/src/test/run-pass/traits/supertrait-default-generics.rs deleted file mode 100644 index e862c0e976b..00000000000 --- a/src/test/run-pass/traits/supertrait-default-generics.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/traits/syntax-trait-polarity.rs b/src/test/run-pass/traits/syntax-trait-polarity.rs deleted file mode 100644 index c6524f5c8e7..00000000000 --- a/src/test/run-pass/traits/syntax-trait-polarity.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -#![feature(optin_builtin_traits)] - -struct TestType; - -impl TestType {} - -trait TestTrait {} - -impl !Send for TestType {} - -struct TestType2(T); - -impl TestType2 {} - -impl !Send for TestType2 {} - -fn main() {} diff --git a/src/test/run-pass/traits/trait-alias-import-cross-crate.rs b/src/test/run-pass/traits/trait-alias-import-cross-crate.rs deleted file mode 100644 index 975542ab49b..00000000000 --- a/src/test/run-pass/traits/trait-alias-import-cross-crate.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/traits/trait-alias-import.rs b/src/test/run-pass/traits/trait-alias-import.rs deleted file mode 100644 index 802a8f15698..00000000000 --- a/src/test/run-pass/traits/trait-alias-import.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/src/test/run-pass/traits/trait-bounds-basic.rs b/src/test/run-pass/traits/trait-bounds-basic.rs deleted file mode 100644 index 8c8a7eb7d9d..00000000000 --- a/src/test/run-pass/traits/trait-bounds-basic.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs b/src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs deleted file mode 100644 index de6c2afa2bb..00000000000 --- a/src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/traits/trait-bounds-in-arc.rs b/src/test/run-pass/traits/trait-bounds-in-arc.rs deleted file mode 100644 index a45d834297e..00000000000 --- a/src/test/run-pass/traits/trait-bounds-in-arc.rs +++ /dev/null @@ -1,109 +0,0 @@ -// run-pass -#![allow(unused_must_use)] -// Tests that a heterogeneous list of existential 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/src/test/run-pass/traits/trait-bounds-recursion.rs b/src/test/run-pass/traits/trait-bounds-recursion.rs deleted file mode 100644 index 0023ff654e8..00000000000 --- a/src/test/run-pass/traits/trait-bounds-recursion.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-bounds.rs b/src/test/run-pass/traits/trait-bounds.rs deleted file mode 100644 index 18382bb59a4..00000000000 --- a/src/test/run-pass/traits/trait-bounds.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/traits/trait-cache-issue-18209.rs b/src/test/run-pass/traits/trait-cache-issue-18209.rs deleted file mode 100644 index 15676e4554a..00000000000 --- a/src/test/run-pass/traits/trait-cache-issue-18209.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-coercion-generic.rs b/src/test/run-pass/traits/trait-coercion-generic.rs deleted file mode 100644 index bf4dda49519..00000000000 --- a/src/test/run-pass/traits/trait-coercion-generic.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/traits/trait-coercion.rs b/src/test/run-pass/traits/trait-coercion.rs deleted file mode 100644 index cba33af1f1a..00000000000 --- a/src/test/run-pass/traits/trait-coercion.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/traits/trait-composition-trivial.rs b/src/test/run-pass/traits/trait-composition-trivial.rs deleted file mode 100644 index 90e5dcd68e8..00000000000 --- a/src/test/run-pass/traits/trait-composition-trivial.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -trait Foo { - fn foo(&self); -} - -trait Bar : Foo { - fn bar(&self); -} - -pub fn main() {} diff --git a/src/test/run-pass/traits/trait-copy-guessing.rs b/src/test/run-pass/traits/trait-copy-guessing.rs deleted file mode 100644 index f031dd9ca48..00000000000 --- a/src/test/run-pass/traits/trait-copy-guessing.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-bound-subst.rs b/src/test/run-pass/traits/trait-default-method-bound-subst.rs deleted file mode 100644 index 6a5d5c8ba2d..00000000000 --- a/src/test/run-pass/traits/trait-default-method-bound-subst.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-bound-subst2.rs b/src/test/run-pass/traits/trait-default-method-bound-subst2.rs deleted file mode 100644 index 78eabba2d23..00000000000 --- a/src/test/run-pass/traits/trait-default-method-bound-subst2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-bound-subst3.rs b/src/test/run-pass/traits/trait-default-method-bound-subst3.rs deleted file mode 100644 index dd39dec4b63..00000000000 --- a/src/test/run-pass/traits/trait-default-method-bound-subst3.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-bound-subst4.rs b/src/test/run-pass/traits/trait-default-method-bound-subst4.rs deleted file mode 100644 index ef133064582..00000000000 --- a/src/test/run-pass/traits/trait-default-method-bound-subst4.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-bound.rs b/src/test/run-pass/traits/trait-default-method-bound.rs deleted file mode 100644 index 0855a9db851..00000000000 --- a/src/test/run-pass/traits/trait-default-method-bound.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-xc-2.rs b/src/test/run-pass/traits/trait-default-method-xc-2.rs deleted file mode 100644 index 5fa1a6cba72..00000000000 --- a/src/test/run-pass/traits/trait-default-method-xc-2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/trait-default-method-xc.rs b/src/test/run-pass/traits/trait-default-method-xc.rs deleted file mode 100644 index 3c20a649613..00000000000 --- a/src/test/run-pass/traits/trait-default-method-xc.rs +++ /dev/null @@ -1,81 +0,0 @@ -// 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/src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs b/src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs deleted file mode 100644 index 3413db6a684..00000000000 --- a/src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/traits/trait-generic.rs b/src/test/run-pass/traits/trait-generic.rs deleted file mode 100644 index 80efe1c9375..00000000000 --- a/src/test/run-pass/traits/trait-generic.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/traits/trait-impl-2.rs b/src/test/run-pass/traits/trait-impl-2.rs deleted file mode 100644 index 804ffec12c2..00000000000 --- a/src/test/run-pass/traits/trait-impl-2.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/traits/trait-impl.rs b/src/test/run-pass/traits/trait-impl.rs deleted file mode 100644 index 14796ce19c8..00000000000 --- a/src/test/run-pass/traits/trait-impl.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs b/src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs deleted file mode 100644 index 62c3ce8030c..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-auto-xc.rs b/src/test/run-pass/traits/trait-inheritance-auto-xc.rs deleted file mode 100644 index e8e651091ad..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-auto-xc.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-auto.rs b/src/test/run-pass/traits/trait-inheritance-auto.rs deleted file mode 100644 index 0be67a55eba..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-auto.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs b/src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs deleted file mode 100644 index 37c2ff63c6a..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs b/src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs deleted file mode 100644 index 8576d29f251..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs b/src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs deleted file mode 100644 index 25159c1adb6..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-cast.rs b/src/test/run-pass/traits/trait-inheritance-cast.rs deleted file mode 100644 index 9070b9d1f56..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-cast.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs b/src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs deleted file mode 100644 index dbefb22cb72..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs b/src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs deleted file mode 100644 index 512c928ca8f..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-diamond.rs b/src/test/run-pass/traits/trait-inheritance-diamond.rs deleted file mode 100644 index 32ad0fb4d41..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-diamond.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs b/src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs deleted file mode 100644 index 77ecbd8eb17..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-multiple-params.rs b/src/test/run-pass/traits/trait-inheritance-multiple-params.rs deleted file mode 100644 index 8ff5ba54185..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-multiple-params.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num.rs b/src/test/run-pass/traits/trait-inheritance-num.rs deleted file mode 100644 index 3d63d78cabb..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num0.rs b/src/test/run-pass/traits/trait-inheritance-num0.rs deleted file mode 100644 index cee52542d38..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num0.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num1.rs b/src/test/run-pass/traits/trait-inheritance-num1.rs deleted file mode 100644 index 663dd3a5eaf..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num1.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num2.rs b/src/test/run-pass/traits/trait-inheritance-num2.rs deleted file mode 100644 index b713c66a37c..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num2.rs +++ /dev/null @@ -1,86 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num3.rs b/src/test/run-pass/traits/trait-inheritance-num3.rs deleted file mode 100644 index c40be6f8354..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num3.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-num5.rs b/src/test/run-pass/traits/trait-inheritance-num5.rs deleted file mode 100644 index f478618f7b5..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-num5.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-overloading-simple.rs b/src/test/run-pass/traits/trait-inheritance-overloading-simple.rs deleted file mode 100644 index c306aa2cda0..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-overloading-simple.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs b/src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs deleted file mode 100644 index 2a9acfdd04a..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-overloading.rs b/src/test/run-pass/traits/trait-inheritance-overloading.rs deleted file mode 100644 index 083643e821f..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-overloading.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs b/src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs deleted file mode 100644 index e8a2bd791a5..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs +++ /dev/null @@ -1,62 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-self.rs b/src/test/run-pass/traits/trait-inheritance-self.rs deleted file mode 100644 index 5f2559f48eb..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-self.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-simple.rs b/src/test/run-pass/traits/trait-inheritance-simple.rs deleted file mode 100644 index ca3a284e597..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-simple.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-static.rs b/src/test/run-pass/traits/trait-inheritance-static.rs deleted file mode 100644 index 16218fbd236..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-static.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-static2.rs b/src/test/run-pass/traits/trait-inheritance-static2.rs deleted file mode 100644 index bc78e1e2328..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-static2.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-subst.rs b/src/test/run-pass/traits/trait-inheritance-subst.rs deleted file mode 100644 index b2b6503666e..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-subst.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-subst2.rs b/src/test/run-pass/traits/trait-inheritance-subst2.rs deleted file mode 100644 index ccc9628c777..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-subst2.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance-visibility.rs b/src/test/run-pass/traits/trait-inheritance-visibility.rs deleted file mode 100644 index 6ad86492674..00000000000 --- a/src/test/run-pass/traits/trait-inheritance-visibility.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/trait-inheritance2.rs b/src/test/run-pass/traits/trait-inheritance2.rs deleted file mode 100644 index 5bfa60b1aec..00000000000 --- a/src/test/run-pass/traits/trait-inheritance2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/traits/trait-item-inside-macro.rs b/src/test/run-pass/traits/trait-item-inside-macro.rs deleted file mode 100644 index 54bf872d028..00000000000 --- a/src/test/run-pass/traits/trait-item-inside-macro.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/src/test/run-pass/traits/trait-object-auto-dedup.rs b/src/test/run-pass/traits/trait-object-auto-dedup.rs deleted file mode 100644 index 39d25eb7fe0..00000000000 --- a/src/test/run-pass/traits/trait-object-auto-dedup.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/traits/trait-object-exclusion.rs b/src/test/run-pass/traits/trait-object-exclusion.rs deleted file mode 100644 index 0b8b0e2f5ef..00000000000 --- a/src/test/run-pass/traits/trait-object-exclusion.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/traits/trait-object-generics.rs b/src/test/run-pass/traits/trait-object-generics.rs deleted file mode 100644 index c18754302b7..00000000000 --- a/src/test/run-pass/traits/trait-object-generics.rs +++ /dev/null @@ -1,43 +0,0 @@ -// 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/src/test/run-pass/traits/trait-object-lifetime-first.rs b/src/test/run-pass/traits/trait-object-lifetime-first.rs deleted file mode 100644 index 33757cb7c0a..00000000000 --- a/src/test/run-pass/traits/trait-object-lifetime-first.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/traits/trait-object-with-lifetime-bound.rs b/src/test/run-pass/traits/trait-object-with-lifetime-bound.rs deleted file mode 100644 index 05aab5e3b08..00000000000 --- a/src/test/run-pass/traits/trait-object-with-lifetime-bound.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/traits/trait-region-pointer-simple.rs b/src/test/run-pass/traits/trait-region-pointer-simple.rs deleted file mode 100644 index 0456ca93115..00000000000 --- a/src/test/run-pass/traits/trait-region-pointer-simple.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/traits/trait-safety-ok-cc.rs b/src/test/run-pass/traits/trait-safety-ok-cc.rs deleted file mode 100644 index 099ba80e5b5..00000000000 --- a/src/test/run-pass/traits/trait-safety-ok-cc.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/traits/trait-safety-ok.rs b/src/test/run-pass/traits/trait-safety-ok.rs deleted file mode 100644 index d456a78b64d..00000000000 --- a/src/test/run-pass/traits/trait-safety-ok.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/traits/trait-static-method-overwriting.rs b/src/test/run-pass/traits/trait-static-method-overwriting.rs deleted file mode 100644 index f669ffae6bb..00000000000 --- a/src/test/run-pass/traits/trait-static-method-overwriting.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/traits/trait-to-str.rs b/src/test/run-pass/traits/trait-to-str.rs deleted file mode 100644 index 9670edbfa2b..00000000000 --- a/src/test/run-pass/traits/trait-to-str.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/traits/trait-where-clause-vs-impl.rs b/src/test/run-pass/traits/trait-where-clause-vs-impl.rs deleted file mode 100644 index 7cfee27efb3..00000000000 --- a/src/test/run-pass/traits/trait-where-clause-vs-impl.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/traits/trait-with-bounds-default.rs b/src/test/run-pass/traits/trait-with-bounds-default.rs deleted file mode 100644 index 31f73d79cc7..00000000000 --- a/src/test/run-pass/traits/trait-with-bounds-default.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs b/src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs deleted file mode 100644 index 7d6a754cc5a..00000000000 --- a/src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/traits-conditional-dispatch.rs b/src/test/run-pass/traits/traits-conditional-dispatch.rs deleted file mode 100644 index a9c194486fe..00000000000 --- a/src/test/run-pass/traits/traits-conditional-dispatch.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/traits/traits-conditional-model-fn.rs b/src/test/run-pass/traits/traits-conditional-model-fn.rs deleted file mode 100644 index 27ce6d93a81..00000000000 --- a/src/test/run-pass/traits/traits-conditional-model-fn.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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/src/test/run-pass/traits/traits-default-method-macro.rs b/src/test/run-pass/traits/traits-default-method-macro.rs deleted file mode 100644 index 2b50ee9b422..00000000000 --- a/src/test/run-pass/traits/traits-default-method-macro.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/traits/traits-default-method-mut.rs b/src/test/run-pass/traits/traits-default-method-mut.rs deleted file mode 100644 index 5f8e983b09c..00000000000 --- a/src/test/run-pass/traits/traits-default-method-mut.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/traits/traits-default-method-self.rs b/src/test/run-pass/traits/traits-default-method-self.rs deleted file mode 100644 index cdf4d1e148c..00000000000 --- a/src/test/run-pass/traits/traits-default-method-self.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/traits/traits-default-method-trivial.rs b/src/test/run-pass/traits/traits-default-method-trivial.rs deleted file mode 100644 index dc41938ec89..00000000000 --- a/src/test/run-pass/traits/traits-default-method-trivial.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/traits/traits-elaborate-type-region.rs b/src/test/run-pass/traits/traits-elaborate-type-region.rs deleted file mode 100644 index 03aef0184ba..00000000000 --- a/src/test/run-pass/traits/traits-elaborate-type-region.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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/src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs b/src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs deleted file mode 100644 index e490967b690..00000000000 --- a/src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/traits/traits-issue-22019.rs b/src/test/run-pass/traits/traits-issue-22019.rs deleted file mode 100644 index 1a887f0f39f..00000000000 --- a/src/test/run-pass/traits/traits-issue-22019.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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/src/test/run-pass/traits/traits-issue-22110.rs b/src/test/run-pass/traits/traits-issue-22110.rs deleted file mode 100644 index bdbfee799f1..00000000000 --- a/src/test/run-pass/traits/traits-issue-22110.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/traits/traits-issue-22655.rs b/src/test/run-pass/traits/traits-issue-22655.rs deleted file mode 100644 index bc08ca0a2ba..00000000000 --- a/src/test/run-pass/traits/traits-issue-22655.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/traits/traits-issue-23003.rs b/src/test/run-pass/traits/traits-issue-23003.rs deleted file mode 100644 index 24c2b2ad660..00000000000 --- a/src/test/run-pass/traits/traits-issue-23003.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/traits/traits-issue-26339.rs b/src/test/run-pass/traits/traits-issue-26339.rs deleted file mode 100644 index bedd87cc4cc..00000000000 --- a/src/test/run-pass/traits/traits-issue-26339.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs b/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs deleted file mode 100644 index 626e1ae71bc..00000000000 --- a/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/traits/traits-repeated-supertrait.rs b/src/test/run-pass/traits/traits-repeated-supertrait.rs deleted file mode 100644 index 391d19c4385..00000000000 --- a/src/test/run-pass/traits/traits-repeated-supertrait.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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/src/test/run-pass/traits/ufcs-trait-object.rs b/src/test/run-pass/traits/ufcs-trait-object.rs deleted file mode 100644 index 700488c22d6..00000000000 --- a/src/test/run-pass/traits/ufcs-trait-object.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/traits/use-trait-before-def.rs b/src/test/run-pass/traits/use-trait-before-def.rs deleted file mode 100644 index 1ee2b941909..00000000000 --- a/src/test/run-pass/traits/use-trait-before-def.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/transmute-non-immediate-to-immediate.rs b/src/test/run-pass/transmute-non-immediate-to-immediate.rs deleted file mode 100644 index cf77c113f4c..00000000000 --- a/src/test/run-pass/transmute-non-immediate-to-immediate.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/transmute-specialization.rs b/src/test/run-pass/transmute-specialization.rs deleted file mode 100644 index 002fba9ce81..00000000000 --- a/src/test/run-pass/transmute-specialization.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![feature(specialization)] - -trait Specializable { type Output; } - -impl Specializable for T { - default type Output = u16; -} - -fn main() { - unsafe { - std::mem::transmute::::Output>(0); - } -} diff --git a/src/test/run-pass/trivial-message.rs b/src/test/run-pass/trivial-message.rs deleted file mode 100644 index 5831e867be5..00000000000 --- a/src/test/run-pass/trivial-message.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/try-block.rs b/src/test/run-pass/try-block.rs deleted file mode 100644 index c29ccc70427..00000000000 --- a/src/test/run-pass/try-block.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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/src/test/run-pass/try-from-int-error-partial-eq.rs b/src/test/run-pass/try-from-int-error-partial-eq.rs deleted file mode 100644 index 6ee4a4cf319..00000000000 --- a/src/test/run-pass/try-from-int-error-partial-eq.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/try-is-identifier-edition2015.rs b/src/test/run-pass/try-is-identifier-edition2015.rs deleted file mode 100644 index dfb05599be6..00000000000 --- a/src/test/run-pass/try-is-identifier-edition2015.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/try-operator-custom.rs b/src/test/run-pass/try-operator-custom.rs deleted file mode 100644 index 9993061ea61..00000000000 --- a/src/test/run-pass/try-operator-custom.rs +++ /dev/null @@ -1,63 +0,0 @@ -// 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/src/test/run-pass/try-operator-hygiene.rs b/src/test/run-pass/try-operator-hygiene.rs deleted file mode 100644 index 0b24b4305ac..00000000000 --- a/src/test/run-pass/try-operator-hygiene.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/try-operator.rs b/src/test/run-pass/try-operator.rs deleted file mode 100644 index 9118e8e7134..00000000000 --- a/src/test/run-pass/try-operator.rs +++ /dev/null @@ -1,193 +0,0 @@ -// 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/src/test/run-pass/try-wait.rs b/src/test/run-pass/try-wait.rs deleted file mode 100644 index d8a07c55cf2..00000000000 --- a/src/test/run-pass/try-wait.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs deleted file mode 100644 index 50451576f9c..00000000000 --- a/src/test/run-pass/try_from.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/tup.rs b/src/test/run-pass/tup.rs deleted file mode 100644 index 160477b0b0a..00000000000 --- a/src/test/run-pass/tup.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/tuple-index-fat-types.rs b/src/test/run-pass/tuple-index-fat-types.rs deleted file mode 100644 index 5dda1ed975c..00000000000 --- a/src/test/run-pass/tuple-index-fat-types.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/tuple-index.rs b/src/test/run-pass/tuple-index.rs deleted file mode 100644 index 3e1d92b42aa..00000000000 --- a/src/test/run-pass/tuple-index.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/tydesc-name.rs b/src/test/run-pass/tydesc-name.rs deleted file mode 100644 index c432e5b5481..00000000000 --- a/src/test/run-pass/tydesc-name.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/type-ascription.rs b/src/test/run-pass/type-ascription.rs deleted file mode 100644 index 7adb074428c..00000000000 --- a/src/test/run-pass/type-ascription.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/type-id-higher-rank-2.rs b/src/test/run-pass/type-id-higher-rank-2.rs deleted file mode 100644 index 5391c849dad..00000000000 --- a/src/test/run-pass/type-id-higher-rank-2.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/type-id-higher-rank.rs b/src/test/run-pass/type-id-higher-rank.rs deleted file mode 100644 index 355d1109941..00000000000 --- a/src/test/run-pass/type-id-higher-rank.rs +++ /dev/null @@ -1,72 +0,0 @@ -// 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/src/test/run-pass/type-in-nested-module.rs b/src/test/run-pass/type-in-nested-module.rs deleted file mode 100644 index 8a92f065f1b..00000000000 --- a/src/test/run-pass/type-in-nested-module.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/type-infer-generalize-ty-var.rs b/src/test/run-pass/type-infer-generalize-ty-var.rs deleted file mode 100644 index a3d6916cbf7..00000000000 --- a/src/test/run-pass/type-infer-generalize-ty-var.rs +++ /dev/null @@ -1,56 +0,0 @@ -// 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/src/test/run-pass/type-namespace.rs b/src/test/run-pass/type-namespace.rs deleted file mode 100644 index 3cc0bc447a5..00000000000 --- a/src/test/run-pass/type-namespace.rs +++ /dev/null @@ -1,7 +0,0 @@ -// 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/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs deleted file mode 100644 index 4b42fddaf5c..00000000000 --- a/src/test/run-pass/type-param-constraints.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/type-param.rs b/src/test/run-pass/type-param.rs deleted file mode 100644 index f5ac19cf73a..00000000000 --- a/src/test/run-pass/type-param.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/type-params-in-for-each.rs b/src/test/run-pass/type-params-in-for-each.rs deleted file mode 100644 index be4a0185eda..00000000000 --- a/src/test/run-pass/type-params-in-for-each.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/type-ptr.rs b/src/test/run-pass/type-ptr.rs deleted file mode 100644 index 7c2438d38bd..00000000000 --- a/src/test/run-pass/type-ptr.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/type-sizes.rs b/src/test/run-pass/type-sizes.rs deleted file mode 100644 index 27433fd770b..00000000000 --- a/src/test/run-pass/type-sizes.rs +++ /dev/null @@ -1,116 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] -#![feature(never_type)] - -use std::mem::size_of; - -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 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, -} - -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::(), 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, &())>()); -} diff --git a/src/test/run-pass/type-use-i1-versus-i8.rs b/src/test/run-pass/type-use-i1-versus-i8.rs deleted file mode 100644 index 7315cd2feea..00000000000 --- a/src/test/run-pass/type-use-i1-versus-i8.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs b/src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs deleted file mode 100644 index 2530a1e966d..00000000000 --- a/src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { - func() -} - -pub fn main() { - unsafe { call_unsafe(|| {}); } -} diff --git a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs deleted file mode 100644 index 1e954f56909..00000000000 --- a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs deleted file mode 100644 index ea7aa5285b0..00000000000 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/typeclasses-eq-example-static.rs b/src/test/run-pass/typeclasses-eq-example-static.rs deleted file mode 100644 index 282d51a93df..00000000000 --- a/src/test/run-pass/typeclasses-eq-example-static.rs +++ /dev/null @@ -1,69 +0,0 @@ -// 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/src/test/run-pass/typeclasses-eq-example.rs b/src/test/run-pass/typeclasses-eq-example.rs deleted file mode 100644 index 8d1d22eb823..00000000000 --- a/src/test/run-pass/typeclasses-eq-example.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/typeid-intrinsic.rs b/src/test/run-pass/typeid-intrinsic.rs deleted file mode 100644 index c2611158e65..00000000000 --- a/src/test/run-pass/typeid-intrinsic.rs +++ /dev/null @@ -1,87 +0,0 @@ -// 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!(other1::id_i32_iterator() != other1::id_u32_iterator()); - assert!(TypeId::of::() != TypeId::of::()); - - // Check fn pointer against collisions - assert!(TypeId::of:: A) -> A>() != - TypeId::of:: A, A) -> A>()); -} diff --git a/src/test/run-pass/typestate-cfg-nesting.rs b/src/test/run-pass/typestate-cfg-nesting.rs deleted file mode 100644 index 5718e0efd18..00000000000 --- a/src/test/run-pass/typestate-cfg-nesting.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/typestate-multi-decl.rs b/src/test/run-pass/typestate-multi-decl.rs deleted file mode 100644 index 9f941620559..00000000000 --- a/src/test/run-pass/typestate-multi-decl.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let (x, y) = (10, 20); - let z = x + y; - assert_eq!(z, 30); -} diff --git a/src/test/run-pass/ufcs-polymorphic-paths.rs b/src/test/run-pass/ufcs-polymorphic-paths.rs deleted file mode 100644 index a14ebd6a41f..00000000000 --- a/src/test/run-pass/ufcs-polymorphic-paths.rs +++ /dev/null @@ -1,154 +0,0 @@ -// 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/src/test/run-pass/ufcs-type-params.rs b/src/test/run-pass/ufcs-type-params.rs deleted file mode 100644 index eee2b55b2a0..00000000000 --- a/src/test/run-pass/ufcs-type-params.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/unary-minus-suffix-inference.rs b/src/test/run-pass/unary-minus-suffix-inference.rs deleted file mode 100644 index a4d0a849484..00000000000 --- a/src/test/run-pass/unary-minus-suffix-inference.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs b/src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs deleted file mode 100644 index ac0a74eebd5..00000000000 --- a/src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs +++ /dev/null @@ -1,16 +0,0 @@ -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/src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs deleted file mode 100644 index dfccb02009e..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs deleted file mode 100644 index a1001673506..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs deleted file mode 100644 index ca1d31ca544..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs deleted file mode 100644 index b2596e49aa7..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs deleted file mode 100644 index cf4d4d3e136..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs deleted file mode 100644 index e23a75ab334..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs deleted file mode 100644 index 9b8a3f4098c..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs deleted file mode 100644 index d47ceea0f4f..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs deleted file mode 100644 index f77733d106d..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs deleted file mode 100644 index fb24df3c24e..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// 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 { - let v = counter; - counter += v; - } - }); - assert_eq!(counter, 88); - - call(move || { - // this mutates a moved copy, and hence doesn't affect original - counter += 1; - }); - assert_eq!(counter, 88); -} diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs deleted file mode 100644 index 39cc260726d..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs deleted file mode 100644 index 1c5e74e593c..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unused_mut)] -// pretty-expanded FIXME #23616 - -fn main() { - let mut unboxed = || {}; - unboxed(); -} diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs deleted file mode 100644 index ba3c61ca22b..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs +++ /dev/null @@ -1,117 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs deleted file mode 100644 index 3ee1aeb109b..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs deleted file mode 100644 index 677cd259a4e..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs deleted file mode 100644 index 851f3d2fe9b..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs deleted file mode 100644 index bd577f7c479..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs deleted file mode 100644 index 740b8b2a72f..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs deleted file mode 100644 index e0c9105760d..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs deleted file mode 100644 index d2eaee30410..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs deleted file mode 100644 index c3abdd8aab0..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs deleted file mode 100644 index 9135c82b4fd..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(fn_traits)] - -fn main() { - let mut zero = || 0; - let x = zero.call_mut(()); - assert_eq!(x, 0); -} diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs deleted file mode 100644 index 73f488a4fbb..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs deleted file mode 100644 index 7ac1ae30f77..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs deleted file mode 100644 index 0fbb504c2ba..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs deleted file mode 100644 index 6381386c4cc..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs deleted file mode 100644 index 3c8ea7d8510..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs deleted file mode 100644 index fc01bd9b6d9..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs deleted file mode 100644 index 86834f49407..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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]: http://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/src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs deleted file mode 100644 index 6a5e5b9c224..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs deleted file mode 100644 index df60b42ab12..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs deleted file mode 100644 index 2df360d4a30..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs deleted file mode 100644 index 4388e6bcf77..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs deleted file mode 100644 index 9b519e63a95..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![deny(unused_mut)] - -// 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; - } - { - let mut x = 0_usize; - move || x += 1; - } - { - let mut x = 0_usize; - move || set(&mut x); - } - { - let mut x = 0_usize; - move || set(&mut x); - } -} diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs deleted file mode 100644 index 2d219643f3e..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs deleted file mode 100644 index 89a273b7a43..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs deleted file mode 100644 index 1449554024c..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs deleted file mode 100644 index 8ada7494e02..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs deleted file mode 100644 index 054f284ea2a..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -fn main() { - let onetime = |x| x; - onetime(0); -} diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs deleted file mode 100644 index 1ca25517c3c..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs deleted file mode 100644 index f86499e2e3f..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass - -// This code used to produce the following ICE: -// -// error: internal compiler error: get_unique_type_id_of_type() - -// unexpected type: closure, -// Closure(syntax::ast::DefId{krate: 0, node: 66}, -// ReScope(63)) -// -// This is a regression test for issue #17021. -// -// compile-flags: -g - -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/src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs b/src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs deleted file mode 100644 index 6f41c35584e..00000000000 --- a/src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![allow(unused_mut)] -// pretty-expanded FIXME #23616 - -fn main() { - let mut zero = || {}; - let () = zero(); -} diff --git a/src/test/run-pass/underscore-lifetimes.rs b/src/test/run-pass/underscore-lifetimes.rs deleted file mode 100644 index a1593880d84..00000000000 --- a/src/test/run-pass/underscore-lifetimes.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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/src/test/run-pass/underscore-method-after-integer.rs b/src/test/run-pass/underscore-method-after-integer.rs deleted file mode 100644 index 7fb8607f97d..00000000000 --- a/src/test/run-pass/underscore-method-after-integer.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -trait Tr : Sized { - fn _method_on_numbers(self) {} -} - -impl Tr for i32 {} - -fn main() { - 42._method_on_numbers(); -} diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs deleted file mode 100644 index a4653317860..00000000000 --- a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs +++ /dev/null @@ -1,7 +0,0 @@ -// edition:2018 - -mod m { pub fn f() {} } -mod n { pub fn g() {} } - -pub use m::f; -pub use n::g; diff --git a/src/test/run-pass/uniform-paths/basic-nested.rs b/src/test/run-pass/uniform-paths/basic-nested.rs deleted file mode 100644 index e4e8b32c70e..00000000000 --- a/src/test/run-pass/uniform-paths/basic-nested.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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/src/test/run-pass/uniform-paths/basic.rs b/src/test/run-pass/uniform-paths/basic.rs deleted file mode 100644 index 4e2e2dedef6..00000000000 --- a/src/test/run-pass/uniform-paths/basic.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/uniform-paths/issue-53691.rs b/src/test/run-pass/uniform-paths/issue-53691.rs deleted file mode 100644 index 5c5ca5b70bb..00000000000 --- a/src/test/run-pass/uniform-paths/issue-53691.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// aux-build:issue-53691.rs - -extern crate issue_53691; - -fn main() { - issue_53691::f(); - issue_53691::g(); -} diff --git a/src/test/run-pass/uniform-paths/macros-nested.rs b/src/test/run-pass/uniform-paths/macros-nested.rs deleted file mode 100644 index a62a28bb94d..00000000000 --- a/src/test/run-pass/uniform-paths/macros-nested.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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/src/test/run-pass/uniform-paths/macros.rs b/src/test/run-pass/uniform-paths/macros.rs deleted file mode 100644 index 31b809f0cfd..00000000000 --- a/src/test/run-pass/uniform-paths/macros.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/src/test/run-pass/uniform-paths/same-crate.rs b/src/test/run-pass/uniform-paths/same-crate.rs deleted file mode 100644 index ce4cc13d9ec..00000000000 --- a/src/test/run-pass/uniform-paths/same-crate.rs +++ /dev/null @@ -1,98 +0,0 @@ -// 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/src/test/run-pass/unify-return-ty.rs b/src/test/run-pass/unify-return-ty.rs deleted file mode 100644 index da1d82e896a..00000000000 --- a/src/test/run-pass/unify-return-ty.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/uninit-empty-types.rs b/src/test/run-pass/uninit-empty-types.rs deleted file mode 100644 index 0d1235776a6..00000000000 --- a/src/test/run-pass/uninit-empty-types.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// Test the uninit() construct returning various empty types. - -// pretty-expanded FIXME #23616 - -use std::mem; - -#[derive(Clone)] -struct Foo; - -#[allow(deprecated)] -pub fn main() { - unsafe { - let _x: Foo = mem::uninitialized(); - let _x: [Foo; 2] = mem::uninitialized(); - } -} diff --git a/src/test/run-pass/union/auxiliary/union.rs b/src/test/run-pass/union/auxiliary/union.rs deleted file mode 100644 index e785e35aeb8..00000000000 --- a/src/test/run-pass/union/auxiliary/union.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub union U { - pub a: u8, - pub b: u16, -} diff --git a/src/test/run-pass/union/union-align.rs b/src/test/run-pass/union/union-align.rs deleted file mode 100644 index edd83a51169..00000000000 --- a/src/test/run-pass/union/union-align.rs +++ /dev/null @@ -1,63 +0,0 @@ -// run-pass -#![allow(dead_code)] - -#![feature(untagged_unions)] - -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))] - 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/src/test/run-pass/union/union-backcomp.rs b/src/test/run-pass/union/union-backcomp.rs deleted file mode 100644 index 4efd4c4d3d3..00000000000 --- a/src/test/run-pass/union/union-backcomp.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/union/union-basic.rs b/src/test/run-pass/union/union-basic.rs deleted file mode 100644 index 73cc9793f2c..00000000000 --- a/src/test/run-pass/union/union-basic.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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/src/test/run-pass/union/union-c-interop.rs b/src/test/run-pass/union/union-c-interop.rs deleted file mode 100644 index 00f04d5b7ff..00000000000 --- a/src/test/run-pass/union/union-c-interop.rs +++ /dev/null @@ -1,37 +0,0 @@ -// 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/src/test/run-pass/union/union-const-codegen.rs b/src/test/run-pass/union/union-const-codegen.rs deleted file mode 100644 index d5b30559595..00000000000 --- a/src/test/run-pass/union/union-const-codegen.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/union/union-const-eval-field.rs b/src/test/run-pass/union/union-const-eval-field.rs deleted file mode 100644 index 3b40a21d80d..00000000000 --- a/src/test/run-pass/union/union-const-eval-field.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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/src/test/run-pass/union/union-drop-assign.rs b/src/test/run-pass/union/union-drop-assign.rs deleted file mode 100644 index c4349c45464..00000000000 --- a/src/test/run-pass/union/union-drop-assign.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -#![allow(unused_assignments)] -#![allow(unions_with_drop_fields)] - -// Drop works for union itself. - -#![feature(untagged_unions)] - -struct S; - -union U { - a: S -} - -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: S }; - assert_eq!(CHECK, 0); - u = U { a: 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/src/test/run-pass/union/union-drop.rs b/src/test/run-pass/union/union-drop.rs deleted file mode 100644 index 2060950dda9..00000000000 --- a/src/test/run-pass/union/union-drop.rs +++ /dev/null @@ -1,60 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unions_with_drop_fields)] - -// Drop works for union itself. - -#![feature(untagged_unions)] - -struct S; - -union U { - a: u8 -} - -union W { - a: S, -} - -union Y { - a: S, -} - -impl Drop for S { - fn drop(&mut self) { - unsafe { CHECK += 10; } - } -} - -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, not 11, dtor of S is not called - { - let y = Y { a: S }; - } - assert_eq!(CHECK, 2); // 2, not 12, dtor of S is not called - } -} diff --git a/src/test/run-pass/union/union-inherent-method.rs b/src/test/run-pass/union/union-inherent-method.rs deleted file mode 100644 index 2e75cce7b10..00000000000 --- a/src/test/run-pass/union/union-inherent-method.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/union/union-macro.rs b/src/test/run-pass/union/union-macro.rs deleted file mode 100644 index e938cd5a614..00000000000 --- a/src/test/run-pass/union/union-macro.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/test/run-pass/union/union-nodrop.rs b/src/test/run-pass/union/union-nodrop.rs deleted file mode 100644 index 4cd64ddb5d6..00000000000 --- a/src/test/run-pass/union/union-nodrop.rs +++ /dev/null @@ -1,59 +0,0 @@ -// run-pass - -#![feature(core_intrinsics)] -#![feature(untagged_unions)] - -#![allow(unions_with_drop_fields)] -#![allow(dead_code)] - -use std::intrinsics::needs_drop; - -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: NeedDrop }, ()).1; - -// A union that scrubs the drop glue from its inner type -union NoDrop {inner: T} - -// 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: T} - -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/src/test/run-pass/union/union-nonzero.rs b/src/test/run-pass/union/union-nonzero.rs deleted file mode 100644 index bd84b46bf3d..00000000000 --- a/src/test/run-pass/union/union-nonzero.rs +++ /dev/null @@ -1,51 +0,0 @@ -// 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/src/test/run-pass/union/union-overwrite.rs b/src/test/run-pass/union/union-overwrite.rs deleted file mode 100644 index 64c60604ba9..00000000000 --- a/src/test/run-pass/union/union-overwrite.rs +++ /dev/null @@ -1,73 +0,0 @@ -// run-pass -#![allow(unions_with_drop_fields)] - -#![feature(untagged_unions)] - -#[repr(C)] -struct Pair(T, U); -#[repr(C)] -struct Triple(T, T, T); - -#[repr(C)] -union U { - a: Pair, - b: B, -} - -#[repr(C)] -union W { - 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/src/test/run-pass/union/union-packed.rs b/src/test/run-pass/union/union-packed.rs deleted file mode 100644 index ceb35d94656..00000000000 --- a/src/test/run-pass/union/union-packed.rs +++ /dev/null @@ -1,171 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(non_snake_case)] - -#![feature(untagged_unions)] - -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)] - 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/src/test/run-pass/union/union-pat-refutability.rs b/src/test/run-pass/union/union-pat-refutability.rs deleted file mode 100644 index ebb06726647..00000000000 --- a/src/test/run-pass/union/union-pat-refutability.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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/src/test/run-pass/union/union-trait-impl.rs b/src/test/run-pass/union/union-trait-impl.rs deleted file mode 100644 index 8a7ac817240..00000000000 --- a/src/test/run-pass/union/union-trait-impl.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/union/union-transmute.rs b/src/test/run-pass/union/union-transmute.rs deleted file mode 100644 index ac7dede98a3..00000000000 --- a/src/test/run-pass/union/union-transmute.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/unique/unique-assign-copy.rs b/src/test/run-pass/unique/unique-assign-copy.rs deleted file mode 100644 index 19469810237..00000000000 --- a/src/test/run-pass/unique/unique-assign-copy.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/unique/unique-assign-drop.rs b/src/test/run-pass/unique/unique-assign-drop.rs deleted file mode 100644 index 32068e79df4..00000000000 --- a/src/test/run-pass/unique/unique-assign-drop.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-assign-generic.rs b/src/test/run-pass/unique/unique-assign-generic.rs deleted file mode 100644 index 2d62ce59ad0..00000000000 --- a/src/test/run-pass/unique/unique-assign-generic.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-assign.rs b/src/test/run-pass/unique/unique-assign.rs deleted file mode 100644 index 5a88df071a0..00000000000 --- a/src/test/run-pass/unique/unique-assign.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/unique/unique-autoderef-field.rs b/src/test/run-pass/unique/unique-autoderef-field.rs deleted file mode 100644 index 0360646f133..00000000000 --- a/src/test/run-pass/unique/unique-autoderef-field.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/unique/unique-autoderef-index.rs b/src/test/run-pass/unique/unique-autoderef-index.rs deleted file mode 100644 index 5a3d17a84ef..00000000000 --- a/src/test/run-pass/unique/unique-autoderef-index.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let i: Box<_> = box vec![100]; - assert_eq!((*i)[0], 100); -} diff --git a/src/test/run-pass/unique/unique-cmp.rs b/src/test/run-pass/unique/unique-cmp.rs deleted file mode 100644 index 7bbc61d25ac..00000000000 --- a/src/test/run-pass/unique/unique-cmp.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-containing-tag.rs b/src/test/run-pass/unique/unique-containing-tag.rs deleted file mode 100644 index f24b3a8645f..00000000000 --- a/src/test/run-pass/unique/unique-containing-tag.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/unique/unique-create.rs b/src/test/run-pass/unique/unique-create.rs deleted file mode 100644 index 3df0f7d55fd..00000000000 --- a/src/test/run-pass/unique/unique-create.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/unique/unique-decl-init-copy.rs b/src/test/run-pass/unique/unique-decl-init-copy.rs deleted file mode 100644 index 6ae95949e84..00000000000 --- a/src/test/run-pass/unique/unique-decl-init-copy.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-decl-init.rs b/src/test/run-pass/unique/unique-decl-init.rs deleted file mode 100644 index 2c7b9d6054f..00000000000 --- a/src/test/run-pass/unique/unique-decl-init.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let i: Box<_> = box 1; - let j = i; - assert_eq!(*j, 1); -} diff --git a/src/test/run-pass/unique/unique-decl-move.rs b/src/test/run-pass/unique/unique-decl-move.rs deleted file mode 100644 index 4a5ee56ea92..00000000000 --- a/src/test/run-pass/unique/unique-decl-move.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let i: Box<_> = box 100; - let j = i; - assert_eq!(*j, 100); -} diff --git a/src/test/run-pass/unique/unique-decl.rs b/src/test/run-pass/unique/unique-decl.rs deleted file mode 100644 index 84a1b2a5b83..00000000000 --- a/src/test/run-pass/unique/unique-decl.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] - - -pub fn main() { - let _: Box; -} - -fn f(_i: Box) -> Box { - panic!(); -} diff --git a/src/test/run-pass/unique/unique-deref.rs b/src/test/run-pass/unique/unique-deref.rs deleted file mode 100644 index 0c6af0f7f97..00000000000 --- a/src/test/run-pass/unique/unique-deref.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let i: Box<_> = box 100; - assert_eq!(*i, 100); -} diff --git a/src/test/run-pass/unique/unique-destructure.rs b/src/test/run-pass/unique/unique-destructure.rs deleted file mode 100644 index 9b9f95dfbca..00000000000 --- a/src/test/run-pass/unique/unique-destructure.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unique/unique-drop-complex.rs b/src/test/run-pass/unique/unique-drop-complex.rs deleted file mode 100644 index 0b7bda83b3f..00000000000 --- a/src/test/run-pass/unique/unique-drop-complex.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/unique/unique-ffi-symbols.rs b/src/test/run-pass/unique/unique-ffi-symbols.rs deleted file mode 100644 index b0fe22bc332..00000000000 --- a/src/test/run-pass/unique/unique-ffi-symbols.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/unique/unique-fn-arg-move.rs b/src/test/run-pass/unique/unique-fn-arg-move.rs deleted file mode 100644 index ff33839e57e..00000000000 --- a/src/test/run-pass/unique/unique-fn-arg-move.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/unique/unique-fn-arg-mut.rs b/src/test/run-pass/unique/unique-fn-arg-mut.rs deleted file mode 100644 index e8bb35e4eb0..00000000000 --- a/src/test/run-pass/unique/unique-fn-arg-mut.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-fn-arg.rs b/src/test/run-pass/unique/unique-fn-arg.rs deleted file mode 100644 index 75f2a767f59..00000000000 --- a/src/test/run-pass/unique/unique-fn-arg.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unique/unique-fn-ret.rs b/src/test/run-pass/unique/unique-fn-ret.rs deleted file mode 100644 index cd44cfa9836..00000000000 --- a/src/test/run-pass/unique/unique-fn-ret.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -fn f() -> Box { - box 100 -} - -pub fn main() { - assert_eq!(f(), box 100); -} diff --git a/src/test/run-pass/unique/unique-generic-assign.rs b/src/test/run-pass/unique/unique-generic-assign.rs deleted file mode 100644 index 9c4405aa8ac..00000000000 --- a/src/test/run-pass/unique/unique-generic-assign.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Issue #976 - - -// pretty-expanded FIXME #23616 - -fn f(x: Box) { - let _x2 = x; -} -pub fn main() { } diff --git a/src/test/run-pass/unique/unique-in-tag.rs b/src/test/run-pass/unique/unique-in-tag.rs deleted file mode 100644 index 8d97ebe6590..00000000000 --- a/src/test/run-pass/unique/unique-in-tag.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/unique/unique-in-vec-copy.rs b/src/test/run-pass/unique/unique-in-vec-copy.rs deleted file mode 100644 index 8907a8b20a7..00000000000 --- a/src/test/run-pass/unique/unique-in-vec-copy.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/unique/unique-in-vec.rs b/src/test/run-pass/unique/unique-in-vec.rs deleted file mode 100644 index 528ea4fb870..00000000000 --- a/src/test/run-pass/unique/unique-in-vec.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let vect : Vec> = vec![box 100]; - assert_eq!(vect[0], box 100); -} diff --git a/src/test/run-pass/unique/unique-init.rs b/src/test/run-pass/unique/unique-init.rs deleted file mode 100644 index c8a150522fd..00000000000 --- a/src/test/run-pass/unique/unique-init.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -// pretty-expanded FIXME #23616 - -#![feature(box_syntax)] - -pub fn main() { - let _i: Box<_> = box 100; -} diff --git a/src/test/run-pass/unique/unique-kinds.rs b/src/test/run-pass/unique/unique-kinds.rs deleted file mode 100644 index f369a1e2a19..00000000000 --- a/src/test/run-pass/unique/unique-kinds.rs +++ /dev/null @@ -1,65 +0,0 @@ -// 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/src/test/run-pass/unique/unique-log.rs b/src/test/run-pass/unique/unique-log.rs deleted file mode 100644 index 27977717706..00000000000 --- a/src/test/run-pass/unique/unique-log.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let i: Box<_> = box 100; - println!("{}", i); -} diff --git a/src/test/run-pass/unique/unique-match-discrim.rs b/src/test/run-pass/unique/unique-match-discrim.rs deleted file mode 100644 index 6e6d7432277..00000000000 --- a/src/test/run-pass/unique/unique-match-discrim.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Issue #961 - -// pretty-expanded FIXME #23616 - -fn altsimple() { - match Box::new(true) { - _ => { } - } -} -pub fn main() { } diff --git a/src/test/run-pass/unique/unique-move-drop.rs b/src/test/run-pass/unique/unique-move-drop.rs deleted file mode 100644 index e1ea58b39ef..00000000000 --- a/src/test/run-pass/unique/unique-move-drop.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/unique/unique-move-temp.rs b/src/test/run-pass/unique/unique-move-temp.rs deleted file mode 100644 index 4f5de50b722..00000000000 --- a/src/test/run-pass/unique/unique-move-temp.rs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/src/test/run-pass/unique/unique-move.rs b/src/test/run-pass/unique/unique-move.rs deleted file mode 100644 index 0f6bff1432b..00000000000 --- a/src/test/run-pass/unique/unique-move.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unique/unique-mutable.rs b/src/test/run-pass/unique/unique-mutable.rs deleted file mode 100644 index 176cf33d488..00000000000 --- a/src/test/run-pass/unique/unique-mutable.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass -#![feature(box_syntax)] - -pub fn main() { - let mut i: Box<_> = box 0; - *i = 1; - assert_eq!(*i, 1); -} diff --git a/src/test/run-pass/unique/unique-object-move.rs b/src/test/run-pass/unique/unique-object-move.rs deleted file mode 100644 index 84e8cdb32b8..00000000000 --- a/src/test/run-pass/unique/unique-object-move.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/unique/unique-pat-2.rs b/src/test/run-pass/unique/unique-pat-2.rs deleted file mode 100644 index c18e029b252..00000000000 --- a/src/test/run-pass/unique/unique-pat-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/unique/unique-pat-3.rs b/src/test/run-pass/unique/unique-pat-3.rs deleted file mode 100644 index e17b5a3ddb4..00000000000 --- a/src/test/run-pass/unique/unique-pat-3.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/unique/unique-pat.rs b/src/test/run-pass/unique/unique-pat.rs deleted file mode 100644 index b32195ac274..00000000000 --- a/src/test/run-pass/unique/unique-pat.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![feature(box_patterns)] -#![feature(box_syntax)] - -fn simple() { - match box true { - box true => { } - _ => { panic!(); } - } -} - -pub fn main() { - simple(); -} diff --git a/src/test/run-pass/unique/unique-rec.rs b/src/test/run-pass/unique/unique-rec.rs deleted file mode 100644 index c8bddd246a8..00000000000 --- a/src/test/run-pass/unique/unique-rec.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unique/unique-send-2.rs b/src/test/run-pass/unique/unique-send-2.rs deleted file mode 100644 index 22f0e6c3a49..00000000000 --- a/src/test/run-pass/unique/unique-send-2.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/src/test/run-pass/unique/unique-send.rs b/src/test/run-pass/unique/unique-send.rs deleted file mode 100644 index a5c7561b9ae..00000000000 --- a/src/test/run-pass/unique/unique-send.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/unique/unique-swap.rs b/src/test/run-pass/unique/unique-swap.rs deleted file mode 100644 index 33a6b3b3ed0..00000000000 --- a/src/test/run-pass/unique/unique-swap.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/unit.rs b/src/test/run-pass/unit.rs deleted file mode 100644 index 4f2dd4194a5..00000000000 --- a/src/test/run-pass/unit.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/unnamed_argument_mode.rs b/src/test/run-pass/unnamed_argument_mode.rs deleted file mode 100644 index 5b7b4002f47..00000000000 --- a/src/test/run-pass/unnamed_argument_mode.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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/src/test/run-pass/unreachable-code-1.rs b/src/test/run-pass/unreachable-code-1.rs deleted file mode 100644 index ee44f399945..00000000000 --- a/src/test/run-pass/unreachable-code-1.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/unreachable-code.rs b/src/test/run-pass/unreachable-code.rs deleted file mode 100644 index 28b938edc63..00000000000 --- a/src/test/run-pass/unreachable-code.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/unsafe-coercion.rs b/src/test/run-pass/unsafe-coercion.rs deleted file mode 100644 index 2478deeab0d..00000000000 --- a/src/test/run-pass/unsafe-coercion.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs b/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs deleted file mode 100644 index 38271cc3c78..00000000000 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs b/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs deleted file mode 100644 index 26acc913e87..00000000000 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/unsafe-pointer-assignability.rs b/src/test/run-pass/unsafe-pointer-assignability.rs deleted file mode 100644 index db822bb6a02..00000000000 --- a/src/test/run-pass/unsafe-pointer-assignability.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -fn f(x: *const isize) { - unsafe { - assert_eq!(*x, 3); - } -} - -pub fn main() { - f(&3); -} diff --git a/src/test/run-pass/unsized-locals/autoderef.rs b/src/test/run-pass/unsized-locals/autoderef.rs deleted file mode 100644 index 7f2d2f9c7ef..00000000000 --- a/src/test/run-pass/unsized-locals/autoderef.rs +++ /dev/null @@ -1,49 +0,0 @@ -// run-pass - -#![feature(unsized_locals)] - -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/src/test/run-pass/unsized-locals/box-fnonce.rs b/src/test/run-pass/unsized-locals/box-fnonce.rs deleted file mode 100644 index 8b2f9b4c9fc..00000000000 --- a/src/test/run-pass/unsized-locals/box-fnonce.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs b/src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs deleted file mode 100644 index 8b39a99da58..00000000000 --- a/src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass - -#![feature(unsized_locals)] - -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/src/test/run-pass/unsized-locals/reference-unsized-locals.rs b/src/test/run-pass/unsized-locals/reference-unsized-locals.rs deleted file mode 100644 index 1560d25d4b0..00000000000 --- a/src/test/run-pass/unsized-locals/reference-unsized-locals.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -#![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/src/test/run-pass/unsized-locals/simple-unsized-locals.rs b/src/test/run-pass/unsized-locals/simple-unsized-locals.rs deleted file mode 100644 index 05955919245..00000000000 --- a/src/test/run-pass/unsized-locals/simple-unsized-locals.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-pass - -#![feature(unsized_locals)] - -fn main() { - let foo: Box<[u8]> = Box::new(*b"foo"); - let _foo: [u8] = *foo; -} diff --git a/src/test/run-pass/unsized-locals/unsized-parameters.rs b/src/test/run-pass/unsized-locals/unsized-parameters.rs deleted file mode 100644 index 3624154d5c4..00000000000 --- a/src/test/run-pass/unsized-locals/unsized-parameters.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - -#![feature(unsized_locals)] - -pub fn f0(_f: dyn FnOnce()) {} -pub fn f1(_s: str) {} -pub fn f2((_x, _y): (i32, [i32])) {} - -fn main() { - let foo = "foo".to_string().into_boxed_str(); - f1(*foo); -} diff --git a/src/test/run-pass/unsized-tuple-impls.rs b/src/test/run-pass/unsized-tuple-impls.rs deleted file mode 100644 index 5e385f33bee..00000000000 --- a/src/test/run-pass/unsized-tuple-impls.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs deleted file mode 100644 index 54304834d4b..00000000000 --- a/src/test/run-pass/unsized.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs deleted file mode 100644 index be4406399fd..00000000000 --- a/src/test/run-pass/unsized2.rs +++ /dev/null @@ -1,97 +0,0 @@ -// 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/src/test/run-pass/unused-move-capture.rs b/src/test/run-pass/unused-move-capture.rs deleted file mode 100644 index e9d4684736e..00000000000 --- a/src/test/run-pass/unused-move-capture.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/unused-move.rs b/src/test/run-pass/unused-move.rs deleted file mode 100644 index 37aee22f85d..00000000000 --- a/src/test/run-pass/unused-move.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs deleted file mode 100644 index a063bef0822..00000000000 --- a/src/test/run-pass/unwind-resource.rs +++ /dev/null @@ -1,39 +0,0 @@ -// 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/src/test/run-pass/unwind-unique.rs b/src/test/run-pass/unwind-unique.rs deleted file mode 100644 index ea3089e747f..00000000000 --- a/src/test/run-pass/unwind-unique.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/use-crate-name-alias.rs b/src/test/run-pass/use-crate-name-alias.rs deleted file mode 100644 index 0920d968585..00000000000 --- a/src/test/run-pass/use-crate-name-alias.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// Issue #1706 -// pretty-expanded FIXME #23616 - -extern crate std as stdlib; - -pub fn main() {} diff --git a/src/test/run-pass/use-import-export.rs b/src/test/run-pass/use-import-export.rs deleted file mode 100644 index 07a6866ba66..00000000000 --- a/src/test/run-pass/use-import-export.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/use-keyword-2.rs b/src/test/run-pass/use-keyword-2.rs deleted file mode 100644 index ebddb5d1a48..00000000000 --- a/src/test/run-pass/use-keyword-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/use-mod.rs b/src/test/run-pass/use-mod.rs deleted file mode 100644 index 84da2e70878..00000000000 --- a/src/test/run-pass/use-mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/use-nested-groups.rs b/src/test/run-pass/use-nested-groups.rs deleted file mode 100644 index 5c739709e9e..00000000000 --- a/src/test/run-pass/use-nested-groups.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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/src/test/run-pass/use.rs b/src/test/run-pass/use.rs deleted file mode 100644 index 1beee4a5143..00000000000 --- a/src/test/run-pass/use.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/use_inline_dtor.rs b/src/test/run-pass/use_inline_dtor.rs deleted file mode 100644 index ac916de4646..00000000000 --- a/src/test/run-pass/use_inline_dtor.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/using-target-feature-unstable.rs b/src/test/run-pass/using-target-feature-unstable.rs deleted file mode 100644 index c5da45c0854..00000000000 --- a/src/test/run-pass/using-target-feature-unstable.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/src/test/run-pass/utf8-bom.rs b/src/test/run-pass/utf8-bom.rs deleted file mode 100644 index a3cb0e9a52a..00000000000 --- a/src/test/run-pass/utf8-bom.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// - -// This file has utf-8 BOM, it should be compiled normally without error. - -pub fn main() {} diff --git a/src/test/run-pass/utf8.rs b/src/test/run-pass/utf8.rs deleted file mode 100644 index 75b6ddf7895..00000000000 --- a/src/test/run-pass/utf8.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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/src/test/run-pass/utf8_chars.rs b/src/test/run-pass/utf8_chars.rs deleted file mode 100644 index d764509813d..00000000000 --- a/src/test/run-pass/utf8_chars.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs deleted file mode 100644 index 3232a11d726..00000000000 --- a/src/test/run-pass/variadic-ffi.rs +++ /dev/null @@ -1,84 +0,0 @@ -// 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/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs deleted file mode 100644 index 74707a98d32..00000000000 --- a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/variance-iterators-in-libcore.rs b/src/test/run-pass/variance-iterators-in-libcore.rs deleted file mode 100644 index 2ab3a8ab5c1..00000000000 --- a/src/test/run-pass/variance-iterators-in-libcore.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - -#![allow(warnings)] - -use std::iter::Zip; - -fn zip_covariant<'a, A, B>(iter: Zip<&'static A, &'static B>) -> Zip<&'a A, &'a B> { iter } - -fn main() { } diff --git a/src/test/run-pass/volatile-fat-ptr.rs b/src/test/run-pass/volatile-fat-ptr.rs deleted file mode 100644 index f73e7e1c391..00000000000 --- a/src/test/run-pass/volatile-fat-ptr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs deleted file mode 100644 index 434361b40de..00000000000 --- a/src/test/run-pass/wait-forked-but-failed-child.rs +++ /dev/null @@ -1,62 +0,0 @@ -// run-pass -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes - -#![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/src/test/run-pass/warn-ctypes-inhibit.rs b/src/test/run-pass/warn-ctypes-inhibit.rs deleted file mode 100644 index ab9634df65c..00000000000 --- a/src/test/run-pass/warn-ctypes-inhibit.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/weak-lang-item.rs b/src/test/run-pass/weak-lang-item.rs deleted file mode 100644 index a429d8fabc7..00000000000 --- a/src/test/run-pass/weak-lang-item.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/src/test/run-pass/weak-new-uninhabited-issue-48493.rs b/src/test/run-pass/weak-new-uninhabited-issue-48493.rs deleted file mode 100644 index 644fc8c2483..00000000000 --- a/src/test/run-pass/weak-new-uninhabited-issue-48493.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -fn main() { - enum Void {} - std::rc::Weak::::new(); - std::sync::Weak::::new(); -} diff --git a/src/test/run-pass/weird-exit-code.rs b/src/test/run-pass/weird-exit-code.rs deleted file mode 100644 index a067b7b5b1f..00000000000 --- a/src/test/run-pass/weird-exit-code.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs deleted file mode 100644 index ca68a5af0dd..00000000000 --- a/src/test/run-pass/weird-exprs.rs +++ /dev/null @@ -1,180 +0,0 @@ -// run-pass - -#![feature(generators)] - -#![allow(non_camel_case_types)] -#![allow(dead_code)] -#![allow(unreachable_code)] -#![allow(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/src/test/run-pass/wf-bound-region-in-object-type.rs b/src/test/run-pass/wf-bound-region-in-object-type.rs deleted file mode 100644 index 7c4dd3ec84f..00000000000 --- a/src/test/run-pass/wf-bound-region-in-object-type.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs b/src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs deleted file mode 100644 index 7c8043b2002..00000000000 --- a/src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs deleted file mode 100644 index cf7d06b6179..00000000000 --- a/src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs deleted file mode 100644 index 6fc570b9b5b..00000000000 --- a/src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clause-region-outlives.rs b/src/test/run-pass/where-clauses/where-clause-region-outlives.rs deleted file mode 100644 index 84925345de1..00000000000 --- a/src/test/run-pass/where-clauses/where-clause-region-outlives.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clauses-cross-crate.rs b/src/test/run-pass/where-clauses/where-clauses-cross-crate.rs deleted file mode 100644 index 9edf0bd5b1d..00000000000 --- a/src/test/run-pass/where-clauses/where-clauses-cross-crate.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clauses-lifetimes.rs b/src/test/run-pass/where-clauses/where-clauses-lifetimes.rs deleted file mode 100644 index 4bfd9e6590f..00000000000 --- a/src/test/run-pass/where-clauses/where-clauses-lifetimes.rs +++ /dev/null @@ -1,10 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clauses-method.rs b/src/test/run-pass/where-clauses/where-clauses-method.rs deleted file mode 100644 index feecff43565..00000000000 --- a/src/test/run-pass/where-clauses/where-clauses-method.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs deleted file mode 100644 index 6964cfa2eb0..00000000000 --- a/src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/src/test/run-pass/where-clauses/where-clauses.rs b/src/test/run-pass/where-clauses/where-clauses.rs deleted file mode 100644 index 905ef7c5e8c..00000000000 --- a/src/test/run-pass/where-clauses/where-clauses.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/wrapping-int-api.rs b/src/test/run-pass/wrapping-int-api.rs deleted file mode 100644 index 2a5baad8b78..00000000000 --- a/src/test/run-pass/wrapping-int-api.rs +++ /dev/null @@ -1,225 +0,0 @@ -// run-pass -// Test inherent wrapping_* methods for {i,u}{size,8,16,32,64}. - -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/src/test/run-pass/write-fmt-errors.rs b/src/test/run-pass/write-fmt-errors.rs deleted file mode 100644 index 7dd98564425..00000000000 --- a/src/test/run-pass/write-fmt-errors.rs +++ /dev/null @@ -1,46 +0,0 @@ -// 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/src/test/run-pass/writealias.rs b/src/test/run-pass/writealias.rs deleted file mode 100644 index 8ba4b09ae29..00000000000 --- a/src/test/run-pass/writealias.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/src/test/run-pass/wrong-hashset-issue-42918.rs b/src/test/run-pass/wrong-hashset-issue-42918.rs deleted file mode 100644 index ef834d915c9..00000000000 --- a/src/test/run-pass/wrong-hashset-issue-42918.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/src/test/run-pass/x86stdcall.rs b/src/test/run-pass/x86stdcall.rs deleted file mode 100644 index fc67ccdc8c4..00000000000 --- a/src/test/run-pass/x86stdcall.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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 = "solaris"))] -pub fn main() { } diff --git a/src/test/run-pass/x86stdcall2.rs b/src/test/run-pass/x86stdcall2.rs deleted file mode 100644 index 563e3aba632..00000000000 --- a/src/test/run-pass/x86stdcall2.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs deleted file mode 100644 index e83ba556078..00000000000 --- a/src/test/run-pass/yield.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs deleted file mode 100644 index 002e590550c..00000000000 --- a/src/test/run-pass/yield1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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/src/test/run-pass/yield2.rs b/src/test/run-pass/yield2.rs deleted file mode 100644 index 376faab0c48..00000000000 --- a/src/test/run-pass/yield2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/src/test/run-pass/z-crate-attr.rs b/src/test/run-pass/z-crate-attr.rs deleted file mode 100644 index 1021774fc5f..00000000000 --- a/src/test/run-pass/z-crate-attr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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/src/test/run-pass/zero-sized/zero-size-type-destructors.rs b/src/test/run-pass/zero-sized/zero-size-type-destructors.rs deleted file mode 100644 index 98b5a439c82..00000000000 --- a/src/test/run-pass/zero-sized/zero-size-type-destructors.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs b/src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs deleted file mode 100644 index 6553c5adbe7..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs b/src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs deleted file mode 100644 index 52edb33d6ad..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs b/src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs deleted file mode 100644 index 03724085f5f..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs b/src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs deleted file mode 100644 index 6c438720e5d..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![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); -} diff --git a/src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs b/src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs deleted file mode 100644 index c541208703b..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -use std::collections::VecDeque; -use std::iter::Iterator; - -fn main() { - const N: usize = 8; - - // Zero sized type - struct Zst; - - // Test that for all possible sequences of push_front / push_back, - // we end up with a deque of the correct size - - for len in 0..N { - let mut tester = VecDeque::with_capacity(len); - assert_eq!(tester.len(), 0); - assert!(tester.capacity() >= len); - for case in 0..(1 << len) { - assert_eq!(tester.len(), 0); - for bit in 0..len { - if case & (1 << bit) != 0 { - tester.push_front(Zst); - } else { - tester.push_back(Zst); - } - } - assert_eq!(tester.len(), len); - assert_eq!(tester.iter().count(), len); - tester.clear(); - } - } -} diff --git a/src/test/run-pass/zero-sized/zero-sized-vec-push.rs b/src/test/run-pass/zero-sized/zero-sized-vec-push.rs deleted file mode 100644 index 9e9fbc972d5..00000000000 --- a/src/test/run-pass/zero-sized/zero-sized-vec-push.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -#![allow(unused_variables)] -use std::iter::Iterator; -use std::vec::Vec; - -fn main() { - const N: usize = 8; - - for len in 0..N { - let mut tester = Vec::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/src/test/ui-fulldeps/ast_stmt_expr_attr.rs b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs new file mode 100644 index 00000000000..c90fe001432 --- /dev/null +++ b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs @@ -0,0 +1,304 @@ +// run-pass + +#![allow(unused_imports)] +// ignore-cross-compile + +#![feature(rustc_private)] + +extern crate syntax; + +use syntax::ast::*; +use syntax::attr::*; +use syntax::ast; +use syntax::source_map::{FilePathMapping, FileName}; +use syntax::parse; +use syntax::parse::{ParseSess, PResult}; +use syntax::parse::new_parser_from_source_str; +use syntax::parse::parser::Parser; +use syntax::parse::token; +use syntax::ptr::P; +use syntax::parse::attr::*; +use syntax::print::pprust; +use std::fmt; + +// Copied out of syntax::util::parser_testing + +pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> { + new_parser_from_source_str(ps, FileName::Custom(source_str.clone()), source_str) +} + +fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where + F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>, +{ + let mut p = string_to_parser(&ps, s); + let x = f(&mut p); + + if ps.span_diagnostic.has_errors() || p.token != token::Eof { + if let Err(mut e) = x { + e.cancel(); + } + return Err(p.fatal("parse error")); + } + + x +} + +fn expr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P> { + with_error_checking_parse(s.to_string(), ps, |p| { + p.parse_expr() + }) +} + +fn stmt<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Stmt> { + with_error_checking_parse(s.to_string(), ps, |p| { + p.parse_stmt().map(|s| s.unwrap()) + }) +} + +fn attr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Attribute> { + with_error_checking_parse(s.to_string(), ps, |p| { + p.parse_attribute(true) + }) +} + +fn str_compare String>(e: &str, expected: &[T], actual: &[T], f: F) { + let expected: Vec<_> = expected.iter().map(|e| f(e)).collect(); + let actual: Vec<_> = actual.iter().map(|e| f(e)).collect(); + + if expected != actual { + panic!("parsed `{}` as {:?}, expected {:?}", e, actual, expected); + } +} + +fn check_expr_attrs(es: &str, expected: &[&str]) { + let ps = ParseSess::new(FilePathMapping::empty()); + let e = expr(es, &ps).expect("parse error"); + let actual = &e.attrs; + str_compare(es, + &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::>(), + &actual, + pprust::attribute_to_string); +} + +fn check_stmt_attrs(es: &str, expected: &[&str]) { + let ps = ParseSess::new(FilePathMapping::empty()); + let e = stmt(es, &ps).expect("parse error"); + let actual = e.node.attrs(); + str_compare(es, + &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::>(), + actual, + pprust::attribute_to_string); +} + +fn reject_expr_parse(es: &str) { + let ps = ParseSess::new(FilePathMapping::empty()); + match expr(es, &ps) { + Ok(_) => panic!("parser did not reject `{}`", es), + Err(mut e) => e.cancel(), + }; +} + +fn reject_stmt_parse(es: &str) { + let ps = ParseSess::new(FilePathMapping::empty()); + match stmt(es, &ps) { + Ok(_) => panic!("parser did not reject `{}`", es), + Err(mut e) => e.cancel(), + }; +} + +fn main() { + syntax::with_default_globals(|| run()); +} + +fn run() { + let both = &["#[attr]", "#![attr]"]; + let outer = &["#[attr]"]; + let none = &[]; + + check_expr_attrs("#[attr] box 0", outer); + reject_expr_parse("box #![attr] 0"); + + check_expr_attrs("#[attr] [#![attr]]", both); + check_expr_attrs("#[attr] [#![attr] 0]", both); + check_expr_attrs("#[attr] [#![attr] 0; 0]", both); + check_expr_attrs("#[attr] [#![attr] 0, 0, 0]", both); + reject_expr_parse("[#[attr]]"); + + check_expr_attrs("#[attr] foo()", outer); + check_expr_attrs("#[attr] x.foo()", outer); + reject_expr_parse("foo#[attr]()"); + reject_expr_parse("foo(#![attr])"); + reject_expr_parse("x.foo(#![attr])"); + reject_expr_parse("x.#[attr]foo()"); + reject_expr_parse("x.#![attr]foo()"); + + check_expr_attrs("#[attr] (#![attr])", both); + check_expr_attrs("#[attr] (#![attr] #[attr] 0,)", both); + check_expr_attrs("#[attr] (#![attr] #[attr] 0, 0)", both); + + check_expr_attrs("#[attr] 0 + #[attr] 0", none); + check_expr_attrs("#[attr] 0 / #[attr] 0", none); + check_expr_attrs("#[attr] 0 & #[attr] 0", none); + check_expr_attrs("#[attr] 0 % #[attr] 0", none); + check_expr_attrs("#[attr] (0 + 0)", outer); + reject_expr_parse("0 + #![attr] 0"); + + check_expr_attrs("#[attr] !0", outer); + check_expr_attrs("#[attr] -0", outer); + reject_expr_parse("!#![attr] 0"); + reject_expr_parse("-#![attr] 0"); + + check_expr_attrs("#[attr] false", outer); + check_expr_attrs("#[attr] 0", outer); + check_expr_attrs("#[attr] 'c'", outer); + + check_expr_attrs("#[attr] x as Y", none); + check_expr_attrs("#[attr] (x as Y)", outer); + reject_expr_parse("x #![attr] as Y"); + + reject_expr_parse("#[attr] if false {}"); + reject_expr_parse("if false #[attr] {}"); + reject_expr_parse("if false {#![attr]}"); + reject_expr_parse("if false {} #[attr] else {}"); + reject_expr_parse("if false {} else #[attr] {}"); + reject_expr_parse("if false {} else {#![attr]}"); + reject_expr_parse("if false {} else #[attr] if true {}"); + reject_expr_parse("if false {} else if true #[attr] {}"); + reject_expr_parse("if false {} else if true {#![attr]}"); + + reject_expr_parse("#[attr] if let Some(false) = false {}"); + reject_expr_parse("if let Some(false) = false #[attr] {}"); + reject_expr_parse("if let Some(false) = false {#![attr]}"); + reject_expr_parse("if let Some(false) = false {} #[attr] else {}"); + reject_expr_parse("if let Some(false) = false {} else #[attr] {}"); + reject_expr_parse("if let Some(false) = false {} else {#![attr]}"); + reject_expr_parse("if let Some(false) = false {} else #[attr] if let Some(false) = true {}"); + reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true #[attr] {}"); + reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true {#![attr]}"); + + check_expr_attrs("#[attr] while true {#![attr]}", both); + + check_expr_attrs("#[attr] while let Some(false) = true {#![attr]}", both); + + check_expr_attrs("#[attr] for x in y {#![attr]}", both); + + check_expr_attrs("#[attr] loop {#![attr]}", both); + + check_expr_attrs("#[attr] match true {#![attr] #[attr] _ => false}", both); + + check_expr_attrs("#[attr] || #[attr] foo", outer); + check_expr_attrs("#[attr] move || #[attr] foo", outer); + check_expr_attrs("#[attr] || #[attr] { #![attr] foo }", outer); + check_expr_attrs("#[attr] move || #[attr] { #![attr] foo }", outer); + check_expr_attrs("#[attr] || { #![attr] foo }", outer); + check_expr_attrs("#[attr] move || { #![attr] foo }", outer); + reject_expr_parse("|| #![attr] foo"); + reject_expr_parse("move || #![attr] foo"); + reject_expr_parse("|| #![attr] {foo}"); + reject_expr_parse("move || #![attr] {foo}"); + + check_expr_attrs("#[attr] { #![attr] }", both); + check_expr_attrs("#[attr] { #![attr] let _ = (); }", both); + check_expr_attrs("#[attr] { #![attr] let _ = (); foo }", both); + + check_expr_attrs("#[attr] x = y", none); + check_expr_attrs("#[attr] (x = y)", outer); + + check_expr_attrs("#[attr] x += y", none); + check_expr_attrs("#[attr] (x += y)", outer); + + check_expr_attrs("#[attr] foo.bar", outer); + check_expr_attrs("(#[attr] foo).bar", none); + + check_expr_attrs("#[attr] foo.0", outer); + check_expr_attrs("(#[attr] foo).0", none); + + check_expr_attrs("#[attr] foo[bar]", outer); + check_expr_attrs("(#[attr] foo)[bar]", none); + + check_expr_attrs("#[attr] 0..#[attr] 0", none); + check_expr_attrs("#[attr] 0..", none); + reject_expr_parse("#[attr] ..#[attr] 0"); + reject_expr_parse("#[attr] .."); + + check_expr_attrs("#[attr] (0..0)", outer); + check_expr_attrs("#[attr] (0..)", outer); + check_expr_attrs("#[attr] (..0)", outer); + check_expr_attrs("#[attr] (..)", outer); + + check_expr_attrs("#[attr] foo::bar::baz", outer); + + check_expr_attrs("#[attr] &0", outer); + check_expr_attrs("#[attr] &mut 0", outer); + check_expr_attrs("#[attr] & #[attr] 0", outer); + check_expr_attrs("#[attr] &mut #[attr] 0", outer); + reject_expr_parse("#[attr] &#![attr] 0"); + reject_expr_parse("#[attr] &mut #![attr] 0"); + + check_expr_attrs("#[attr] break", outer); + check_expr_attrs("#[attr] continue", outer); + check_expr_attrs("#[attr] return", outer); + + check_expr_attrs("#[attr] foo!()", outer); + check_expr_attrs("#[attr] foo!(#![attr])", outer); + check_expr_attrs("#[attr] foo![]", outer); + check_expr_attrs("#[attr] foo![#![attr]]", outer); + check_expr_attrs("#[attr] foo!{}", outer); + check_expr_attrs("#[attr] foo!{#![attr]}", outer); + + check_expr_attrs("#[attr] Foo { #![attr] bar: baz }", both); + check_expr_attrs("#[attr] Foo { #![attr] ..foo }", both); + check_expr_attrs("#[attr] Foo { #![attr] bar: baz, ..foo }", both); + + check_expr_attrs("#[attr] (#![attr] 0)", both); + + // Look at statements in their natural habitat... + check_expr_attrs("{ + #[attr] let _ = 0; + #[attr] 0; + #[attr] foo!(); + #[attr] foo!{} + #[attr] foo![]; + }", none); + + check_stmt_attrs("#[attr] let _ = 0", outer); + check_stmt_attrs("#[attr] 0", outer); + check_stmt_attrs("#[attr] {#![attr]}", both); + check_stmt_attrs("#[attr] foo!()", outer); + check_stmt_attrs("#[attr] foo![]", outer); + check_stmt_attrs("#[attr] foo!{}", outer); + + reject_stmt_parse("#[attr] #![attr] let _ = 0"); + reject_stmt_parse("#[attr] #![attr] 0"); + reject_stmt_parse("#[attr] #![attr] foo!()"); + reject_stmt_parse("#[attr] #![attr] foo![]"); + reject_stmt_parse("#[attr] #![attr] foo!{}"); + + // FIXME: Allow attributes in pattern constexprs? + // note: requires parens in patterns to allow disambiguation + + reject_expr_parse("match 0 { + 0..=#[attr] 10 => () + }"); + reject_expr_parse("match 0 { + 0..=#[attr] -10 => () + }"); + reject_expr_parse("match 0 { + 0..=-#[attr] 10 => () + }"); + reject_expr_parse("match 0 { + 0..=#[attr] FOO => () + }"); + + // make sure we don't catch this bug again... + reject_expr_parse("{ + fn foo() { + #[attr]; + } + }"); + reject_expr_parse("{ + fn foo() { + #[attr] + } + }"); +} diff --git a/src/test/ui-fulldeps/auxiliary/issue-13560-1.rs b/src/test/ui-fulldeps/auxiliary/issue-13560-1.rs new file mode 100644 index 00000000000..c3a2ae679bf --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-13560-1.rs @@ -0,0 +1,3 @@ +// no-prefer-dynamic + +#![crate_type = "dylib"] diff --git a/src/test/ui-fulldeps/auxiliary/issue-13560-2.rs b/src/test/ui-fulldeps/auxiliary/issue-13560-2.rs new file mode 100644 index 00000000000..39c261e1162 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-13560-2.rs @@ -0,0 +1,3 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] diff --git a/src/test/ui-fulldeps/auxiliary/issue-13560-3.rs b/src/test/ui-fulldeps/auxiliary/issue-13560-3.rs new file mode 100644 index 00000000000..e991bcc1a02 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-13560-3.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[macro_use] #[no_link] extern crate issue_13560_1 as t1; +#[macro_use] extern crate issue_13560_2 as t2; diff --git a/src/test/ui-fulldeps/auxiliary/issue-16822.rs b/src/test/ui-fulldeps/auxiliary/issue-16822.rs new file mode 100644 index 00000000000..9042dd39117 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-16822.rs @@ -0,0 +1,20 @@ +#![crate_type="lib"] + +use std::cell::RefCell; + +pub struct Window{ + pub data: RefCell +} + +impl Window { + pub fn update(&self, e: i32) { + match e { + 1 => self.data.borrow_mut().update(), + _ => {} + } + } +} + +pub trait Update { + fn update(&mut self); +} diff --git a/src/test/ui-fulldeps/auxiliary/issue-18502.rs b/src/test/ui-fulldeps/auxiliary/issue-18502.rs new file mode 100644 index 00000000000..4d4230607aa --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-18502.rs @@ -0,0 +1,21 @@ +#![crate_type="lib"] + +struct Foo; +// This is the ICE trigger +struct Formatter; + +trait Show { + fn fmt(&self); +} + +impl Show for Foo { + fn fmt(&self) {} +} + +fn bar(f: extern "Rust" fn(&T), t: &T) { } + +// ICE requirement: this has to be marked as inline +#[inline] +pub fn baz() { + bar(Show::fmt, &Foo); +} diff --git a/src/test/ui-fulldeps/auxiliary/issue-24106.rs b/src/test/ui-fulldeps/auxiliary/issue-24106.rs new file mode 100644 index 00000000000..2c6a6034806 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-24106.rs @@ -0,0 +1,13 @@ +#![crate_type="lib"] + +enum E { E0 = 0, E1 = 1 } +const E0_U8: u8 = E::E0 as u8; +const E1_U8: u8 = E::E1 as u8; + +pub fn go() { + match 0 { + E0_U8 => (), + E1_U8 => (), + _ => (), + } +} diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs new file mode 100644 index 00000000000..ad42ee1d1ec --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -0,0 +1,57 @@ +#![feature(box_syntax, plugin, plugin_registrar, rustc_private)] +#![crate_type = "dylib"] + +#[macro_use] +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; +extern crate syntax; + +use rustc_plugin::Registry; +use syntax::attr; +use syntax::ext::base::*; +use syntax::feature_gate::AttributeType::Whitelisted; +use syntax::symbol::Symbol; + +use rustc::hir; +use rustc::hir::intravisit; +use rustc::hir::map as hir_map; +use hir::Node; +use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; +use rustc::ty; +use syntax::{ast, source_map}; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_late_lint_pass(box MissingWhitelistedAttrPass); + reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); +} + +declare_lint! { + MISSING_WHITELISTED_ATTR, + Deny, + "Checks for missing `whitelisted_attr` attribute" +} + +declare_lint_pass!(MissingWhitelistedAttrPass => [MISSING_WHITELISTED_ATTR]); + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass { + fn check_fn(&mut self, + cx: &LateContext<'a, 'tcx>, + _: intravisit::FnKind<'tcx>, + _: &'tcx hir::FnDecl, + _: &'tcx hir::Body, + span: source_map::Span, + id: hir::HirId) { + + let item = match cx.tcx.hir().get(id) { + Node::Item(item) => item, + _ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(id)), + }; + + if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) { + cx.span_lint(MISSING_WHITELISTED_ATTR, span, + "Missing 'whitelisted_attr' attribute"); + } + } +} diff --git a/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs b/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs new file mode 100644 index 00000000000..8917693d45e --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs @@ -0,0 +1,37 @@ +// ignore-musl - dlsym doesn't see symbols without "-C link-arg=-Wl,--export-dynamic" + +#![feature(rustc_private)] + +// We're testing linkage visibility; the compiler warns us, but we want to +// do the runtime check that these functions aren't exported. +#![allow(private_no_mangle_fns)] + +extern crate rustc_metadata; + +use rustc_metadata::dynamic_lib::DynamicLibrary; + +#[no_mangle] +pub fn foo() { bar(); } + +pub fn foo2() { + fn bar2() { + bar(); + } + bar2(); +} + +#[no_mangle] +fn bar() { } + +#[allow(dead_code)] +#[no_mangle] +fn baz() { } + +pub fn test() { + let lib = DynamicLibrary::open(None).unwrap(); + unsafe { + assert!(lib.symbol::("foo").is_ok()); + assert!(lib.symbol::("baz").is_ok()); + assert!(lib.symbol::("bar").is_ok()); + } +} diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs new file mode 100644 index 00000000000..2826ae75bee --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -0,0 +1,74 @@ +// force-host + +#![feature(plugin_registrar, rustc_private)] +#![feature(box_syntax)] + +#[macro_use] extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; +extern crate syntax; + +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc_plugin::Registry; +use rustc::hir; +use syntax::attr; +use syntax::symbol::Symbol; + +macro_rules! fake_lint_pass { + ($struct:ident, $lints:expr, $($attr:expr),*) => { + struct $struct; + + impl LintPass for $struct { + fn name(&self) -> &'static str { + stringify!($struct) + } + + fn get_lints(&self) -> LintArray { + $lints + } + } + + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { + fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { + $( + if !attr::contains_name(&krate.attrs, $attr) { + cx.span_lint(CRATE_NOT_OKAY, krate.span, + &format!("crate is not marked with #![{}]", $attr)); + } + )* + } + } + + } +} + +declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); +declare_lint!(CRATE_NOT_RED, Warn, "crate not marked with #![crate_red]"); +declare_lint!(CRATE_NOT_BLUE, Warn, "crate not marked with #![crate_blue]"); +declare_lint!(CRATE_NOT_GREY, Warn, "crate not marked with #![crate_grey]"); +declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); + +fake_lint_pass! { + PassOkay, + lint_array!(CRATE_NOT_OKAY), // Single lint + Symbol::intern("rustc_crate_okay") +} + +fake_lint_pass! { + PassRedBlue, + lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints + Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") +} + +fake_lint_pass! { + PassGreyGreen, + lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma + Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_late_lint_pass(box PassOkay); + reg.register_late_lint_pass(box PassRedBlue); + reg.register_late_lint_pass(box PassGreyGreen); +} diff --git a/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs b/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs new file mode 100644 index 00000000000..1832fee4347 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs @@ -0,0 +1,20 @@ +// force-host + +#![feature(plugin_registrar)] +#![feature(rustc_private)] + +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; + +use rustc_plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + // This pass is built in to LLVM. + // + // Normally, we would name a pass that was registered through + // C++ static object constructors in the same .so file as the + // plugin registrar. + reg.register_llvm_pass("gvn"); +} diff --git a/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs new file mode 100644 index 00000000000..954a1e554da --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs @@ -0,0 +1,5 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} diff --git a/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs new file mode 100644 index 00000000000..6e446241d55 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs @@ -0,0 +1,13 @@ +// force-host + +#![feature(plugin_registrar)] +#![feature(rustc_private)] + +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; + +use rustc_plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(_reg: &mut Registry) {} diff --git a/src/test/ui-fulldeps/auxiliary/macro-crate-test.rs b/src/test/ui-fulldeps/auxiliary/macro-crate-test.rs new file mode 100644 index 00000000000..d9b2740e476 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/macro-crate-test.rs @@ -0,0 +1,35 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(rustc_private)] + +extern crate syntax; +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; +extern crate syntax_pos; +extern crate proc_macro; + +use proc_macro::{TokenTree, TokenStream}; + +#[proc_macro_attribute] +pub fn rustc_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/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs b/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs new file mode 100644 index 00000000000..c22605afd0c --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs @@ -0,0 +1,26 @@ +// force-host + +#![feature(plugin_registrar)] +#![feature(box_syntax, rustc_private)] + +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; + +use std::any::Any; +use std::cell::RefCell; +use rustc_plugin::Registry; + +struct Foo { + foo: isize +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +#[plugin_registrar] +pub fn registrar(_: &mut Registry) { + thread_local!(static FOO: RefCell>> = RefCell::new(None)); + FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box)); +} diff --git a/src/test/ui-fulldeps/auxiliary/plugin-args.rs b/src/test/ui-fulldeps/auxiliary/plugin-args.rs new file mode 100644 index 00000000000..36cee82893a --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/plugin-args.rs @@ -0,0 +1,44 @@ +// force-host + +#![feature(plugin_registrar)] +#![feature(box_syntax, rustc_private)] + +extern crate syntax; +extern crate syntax_pos; +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; + +use std::borrow::ToOwned; +use syntax::ast; +use syntax::ext::build::AstBuilder; +use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; +use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager}; +use syntax::print::pprust; +use syntax::symbol::Symbol; +use syntax_pos::Span; +use syntax::tokenstream::TokenStream; +use rustc_plugin::Registry; + +struct Expander { + args: Vec, +} + +impl TTMacroExpander for Expander { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt, + sp: Span, + _: TokenStream) -> Box { + let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) + .collect::>().join(", "); + MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) + } +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + let args = reg.args().to_owned(); + reg.register_syntax_extension(Symbol::intern("plugin_args"), SyntaxExtension::default( + SyntaxExtensionKind::LegacyBang(Box::new(Expander { args })), reg.sess.edition() + )); +} diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs new file mode 100644 index 00000000000..07302b6e68b --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs @@ -0,0 +1,70 @@ +// WARNING WARNING WARNING WARNING WARNING +// ======================================= +// +// This code also appears in src/doc/unstable-book/src/language-features/plugin.md. +// Please keep the two copies in sync! FIXME: have rustdoc read this file + +// force-host + +#![crate_type="dylib"] +#![feature(plugin_registrar, rustc_private)] + +extern crate syntax; +extern crate syntax_pos; +extern crate rustc; +extern crate rustc_plugin; +extern crate rustc_driver; + +use syntax::parse::token::{self, Token}; +use syntax::tokenstream::TokenTree; +use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; +use syntax::ext::build::AstBuilder; // A trait for expr_usize. +use syntax_pos::Span; +use rustc_plugin::Registry; + +fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) + -> Box { + + static NUMERALS: &'static [(&'static str, usize)] = &[ + ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), + ("C", 100), ("XC", 90), ("L", 50), ("XL", 40), + ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), + ("I", 1)]; + + if args.len() != 1 { + cx.span_err( + sp, + &format!("argument should be a single identifier, but got {} arguments", args.len())); + return DummyResult::any(sp); + } + + let text = match args[0] { + TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(), + _ => { + cx.span_err(sp, "argument should be a single identifier"); + return DummyResult::any(sp); + } + }; + + let mut text = &*text; + let mut total = 0; + while !text.is_empty() { + match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) { + Some(&(rn, val)) => { + total += val; + text = &text[rn.len()..]; + } + None => { + cx.span_err(sp, "invalid Roman numeral"); + return DummyResult::any(sp); + } + } + } + + MacEager::expr(cx.expr_usize(sp, total)) +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("rn", expand_rn); +} diff --git a/src/test/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs b/src/test/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs new file mode 100644 index 00000000000..8b00fb81cd2 --- /dev/null +++ b/src/test/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs @@ -0,0 +1,7 @@ +// force-host + +#![crate_type = "dylib"] + +pub fn the_answer() -> isize { + 2 +} diff --git a/src/test/ui-fulldeps/compiler-calls.rs b/src/test/ui-fulldeps/compiler-calls.rs new file mode 100644 index 00000000000..ea24f5809d5 --- /dev/null +++ b/src/test/ui-fulldeps/compiler-calls.rs @@ -0,0 +1,31 @@ +// run-pass +// Test that the Callbacks interface to the compiler works. + +// ignore-cross-compile +// ignore-stage1 + +#![feature(rustc_private)] + +extern crate rustc_driver; +extern crate rustc_interface; + +use rustc_interface::interface; + +struct TestCalls<'a> { + count: &'a mut u32 +} + +impl rustc_driver::Callbacks for TestCalls<'_> { + fn config(&mut self, _config: &mut interface::Config) { + *self.count *= 2; + } +} + +fn main() { + let mut count = 1; + let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()]; + rustc_driver::report_ices_to_stderr_if_any(|| { + rustc_driver::run_compiler(&args, &mut TestCalls { count: &mut count }, None, None).ok(); + }).ok(); + assert_eq!(count, 2); +} diff --git a/src/test/ui-fulldeps/create-dir-all-bare.rs b/src/test/ui-fulldeps/create-dir-all-bare.rs new file mode 100644 index 00000000000..4554680ec24 --- /dev/null +++ b/src/test/ui-fulldeps/create-dir-all-bare.rs @@ -0,0 +1,11 @@ +// run-pass + +use std::env; +use std::fs; +use std::path::PathBuf; + +fn main() { + let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); + env::set_current_dir(&path).unwrap(); + fs::create_dir_all("create-dir-all-bare").unwrap(); +} diff --git a/src/test/ui-fulldeps/derive-no-std-not-supported.rs b/src/test/ui-fulldeps/derive-no-std-not-supported.rs new file mode 100644 index 00000000000..d09b1922a7b --- /dev/null +++ b/src/test/ui-fulldeps/derive-no-std-not-supported.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(dead_code)] +#![feature(rustc_private)] +#![no_std] + +extern crate serialize as rustc_serialize; + +#[derive(RustcEncodable)] +struct Bar { + x: u32, +} + +#[derive(RustcDecodable)] +struct Baz { + x: u32, +} + +fn main() { + Bar { x: 0 }; + Baz { x: 0 }; +} diff --git a/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs b/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs new file mode 100644 index 00000000000..877fb57a251 --- /dev/null +++ b/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(unused_imports)] + +#![feature(box_syntax)] +#![feature(rustc_private)] + +extern crate serialize; +use serialize as rustc_serialize; + +use serialize::{Encodable, Decodable}; +use serialize::json; + +#[derive(RustcEncodable, RustcDecodable)] +struct A { + foo: Box<[bool]>, +} + +fn main() { + let obj = A { foo: Box::new([true, false]) }; + let s = json::encode(&obj).unwrap(); + let obj2: A = json::decode(&s).unwrap(); + assert_eq!(obj.foo, obj2.foo); +} diff --git a/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs new file mode 100644 index 00000000000..a35b681641a --- /dev/null +++ b/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs @@ -0,0 +1,37 @@ +// run-pass + +#![allow(unused_imports)] +// This briefly tests the capability of `Cell` and `RefCell` to implement the +// `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]` + + +#![feature(rustc_private)] + +extern crate serialize; +use serialize as rustc_serialize; + +use std::cell::{Cell, RefCell}; +use serialize::{Encodable, Decodable}; +use serialize::json; + +#[derive(RustcEncodable, RustcDecodable)] +struct A { + baz: isize +} + +#[derive(RustcEncodable, RustcDecodable)] +struct B { + foo: Cell, + bar: RefCell, +} + +fn main() { + let obj = B { + foo: Cell::new(true), + bar: RefCell::new( A { baz: 2 } ) + }; + let s = json::encode(&obj).unwrap(); + let obj2: B = json::decode(&s).unwrap(); + assert_eq!(obj.foo.get(), obj2.foo.get()); + assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz); +} diff --git a/src/test/ui-fulldeps/deriving-global.rs b/src/test/ui-fulldeps/deriving-global.rs new file mode 100644 index 00000000000..b59d55ff213 --- /dev/null +++ b/src/test/ui-fulldeps/deriving-global.rs @@ -0,0 +1,35 @@ +// run-pass + +#![feature(rustc_private)] + +extern crate serialize; +use serialize as rustc_serialize; + +mod submod { + // if any of these are implemented without global calls for any + // function calls, then being in a submodule will (correctly) + // cause errors about unrecognised module `std` (or `extra`) + #[derive(PartialEq, PartialOrd, Eq, Ord, + Hash, + Clone, + Debug, + RustcEncodable, RustcDecodable)] + enum A { A1(usize), A2(isize) } + + #[derive(PartialEq, PartialOrd, Eq, Ord, + Hash, + Clone, + Debug, + RustcEncodable, RustcDecodable)] + struct B { x: usize, y: isize } + + #[derive(PartialEq, PartialOrd, Eq, Ord, + Hash, + Clone, + Debug, + RustcEncodable, RustcDecodable)] + struct C(usize, isize); + +} + +pub fn main() {} diff --git a/src/test/ui-fulldeps/deriving-hygiene.rs b/src/test/ui-fulldeps/deriving-hygiene.rs new file mode 100644 index 00000000000..0d7439ef872 --- /dev/null +++ b/src/test/ui-fulldeps/deriving-hygiene.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(non_upper_case_globals)] +#![feature(rustc_private)] +extern crate serialize; +use serialize as rustc_serialize; + +pub const other: u8 = 1; +pub const f: u8 = 1; +pub const d: u8 = 1; +pub const s: u8 = 1; +pub const state: u8 = 1; +pub const cmp: u8 = 1; + +#[derive(Ord,Eq,PartialOrd,PartialEq,Debug,RustcDecodable,RustcEncodable,Hash)] +struct Foo {} + +fn main() { +} diff --git a/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs b/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs new file mode 100644 index 00000000000..cf188d9efa3 --- /dev/null +++ b/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs @@ -0,0 +1,43 @@ +// run-pass + +#![allow(unknown_lints)] +// Check that an arena (TypedArena) can carry elements whose drop +// methods might access borrowed data, as long as the borrowed data +// has lifetime that strictly outlives the arena itself. +// +// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which +// shows a similar setup, but restricts `f` so that the struct `C<'a>` +// is force-fed a lifetime equal to that of the borrowed arena. + +#![allow(unstable)] +#![feature(rustc_private)] + +extern crate arena; + +use arena::TypedArena; + +trait HasId { fn count(&self) -> usize; } + +struct CheckId { v: T } + +// In the code below, the impl of HasId for `&'a usize` does not +// actually access the borrowed data, but the point is that the +// interface to CheckId does not (and cannot) know that, and therefore +// when encountering a value V of type CheckId, we must +// conservatively force the type S to strictly outlive V. +impl Drop for CheckId { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +struct C<'a> { _v: CheckId<&'a usize>, } + +impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } } + +fn f<'a, 'b>(_arena: &'a TypedArena>) {} + +fn main() { + let arena: TypedArena = TypedArena::default(); + f(&arena); +} diff --git a/src/test/ui-fulldeps/empty-struct-braces-derive.rs b/src/test/ui-fulldeps/empty-struct-braces-derive.rs new file mode 100644 index 00000000000..68b407423aa --- /dev/null +++ b/src/test/ui-fulldeps/empty-struct-braces-derive.rs @@ -0,0 +1,56 @@ +// run-pass +// `#[derive(Trait)]` works for empty structs/variants with braces or parens. + +#![feature(rustc_private)] + +extern crate serialize as rustc_serialize; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, + Default, Debug, RustcEncodable, RustcDecodable)] +struct S {} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, + Default, Debug, RustcEncodable, RustcDecodable)] +struct Z(); + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, + Debug, RustcEncodable, RustcDecodable)] +enum E { + V {}, + U, + W(), +} + +fn main() { + let s = S {}; + let s1 = s; + let s2 = s.clone(); + assert_eq!(s, s1); + assert_eq!(s, s2); + assert!(!(s < s1)); + assert_eq!(format!("{:?}", s), "S"); + + let z = Z(); + let z1 = z; + let z2 = z.clone(); + assert_eq!(z, z1); + assert_eq!(z, z2); + assert!(!(z < z1)); + assert_eq!(format!("{:?}", z), "Z"); + + let e = E::V {}; + let e1 = e; + let e2 = e.clone(); + assert_eq!(e, e1); + assert_eq!(e, e2); + assert!(!(e < e1)); + assert_eq!(format!("{:?}", e), "V"); + + let e = E::W(); + let e1 = e; + let e2 = e.clone(); + assert_eq!(e, e1); + assert_eq!(e, e2); + assert!(!(e < e1)); + assert_eq!(format!("{:?}", e), "W"); +} diff --git a/src/test/ui-fulldeps/extern-mod-syntax.rs b/src/test/ui-fulldeps/extern-mod-syntax.rs new file mode 100644 index 00000000000..258ab0dbe95 --- /dev/null +++ b/src/test/ui-fulldeps/extern-mod-syntax.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(unused_imports)] +#![feature(rustc_private)] + +extern crate serialize; +use serialize::json::Object; + +pub fn main() { + println!("Hello world!"); +} diff --git a/src/test/ui-fulldeps/issue-11881.rs b/src/test/ui-fulldeps/issue-11881.rs new file mode 100644 index 00000000000..c8893e62941 --- /dev/null +++ b/src/test/ui-fulldeps/issue-11881.rs @@ -0,0 +1,52 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_imports)] + +#![feature(rustc_private)] + +extern crate serialize; +use serialize as rustc_serialize; + +use std::io::Cursor; +use std::io::prelude::*; +use std::fmt; +use std::slice; + +use serialize::{Encodable, Encoder}; +use serialize::json; +use serialize::opaque; + +#[derive(RustcEncodable)] +struct Foo { + baz: bool, +} + +#[derive(RustcEncodable)] +struct Bar { + froboz: usize, +} + +enum WireProtocol { + JSON, + Opaque, + // ... +} + +fn encode_json(val: &T, wr: &mut Cursor>) { + write!(wr, "{}", json::as_json(val)); +} +fn encode_opaque(val: &T, wr: Vec) { + let mut encoder = opaque::Encoder::new(wr); + val.encode(&mut encoder); +} + +pub fn main() { + let target = Foo{baz: false,}; + let proto = WireProtocol::JSON; + match proto { + WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())), + WireProtocol::Opaque => encode_opaque(&target, Vec::new()) + } +} diff --git a/src/test/ui-fulldeps/issue-13560.rs b/src/test/ui-fulldeps/issue-13560.rs new file mode 100644 index 00000000000..5f7d647e230 --- /dev/null +++ b/src/test/ui-fulldeps/issue-13560.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-13560-1.rs +// aux-build:issue-13560-2.rs +// aux-build:issue-13560-3.rs + +// Regression test for issue #13560, the test itself is all in the dependent +// libraries. The fail which previously failed to compile is the one numbered 3. + +extern crate issue_13560_2 as t2; +extern crate issue_13560_3 as t3; + +fn main() {} diff --git a/src/test/ui-fulldeps/issue-14021.rs b/src/test/ui-fulldeps/issue-14021.rs new file mode 100644 index 00000000000..49fa4492fa1 --- /dev/null +++ b/src/test/ui-fulldeps/issue-14021.rs @@ -0,0 +1,25 @@ +// run-pass + +#![allow(unused_mut)] +#![allow(unused_imports)] +#![feature(rustc_private)] + +extern crate serialize; +extern crate serialize as rustc_serialize; + +use serialize::{Encodable, Decodable}; +use serialize::json; + +#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] +struct UnitLikeStruct; + +pub fn main() { + let obj = UnitLikeStruct; + let json_str: String = json::encode(&obj).unwrap(); + + let json_object = json::from_str(&json_str); + let mut decoder = json::Decoder::new(json_object.unwrap()); + let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder).unwrap(); + + assert_eq!(obj, decoded_obj); +} diff --git a/src/test/ui-fulldeps/issue-15149.rs b/src/test/ui-fulldeps/issue-15149.rs new file mode 100644 index 00000000000..c80628aabc8 --- /dev/null +++ b/src/test/ui-fulldeps/issue-15149.rs @@ -0,0 +1,56 @@ +// run-pass + +#![allow(unused_variables)] +// no-prefer-dynamic +// ignore-cross-compile + +use std::env; +use std::fs; +use std::process; +use std::str; +use std::path::PathBuf; + +fn main() { + // If we're the child, make sure we were invoked correctly + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + // FIXME: This should check the whole `args[0]` instead of just + // checking that it ends_with the executable name. This + // is needed because of Windows, which has a different behavior. + // See #15149 for more info. + return assert!(args[0].ends_with(&format!("mytest{}", + env::consts::EXE_SUFFIX))); + } + + test(); +} + +fn test() { + // If we're the parent, copy our own binary to a new directory. + let my_path = env::current_exe().unwrap(); + let my_dir = my_path.parent().unwrap(); + + let child_dir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); + let child_dir = child_dir.join("issue-15140-child"); + fs::create_dir_all(&child_dir).unwrap(); + + let child_path = child_dir.join(&format!("mytest{}", + env::consts::EXE_SUFFIX)); + fs::copy(&my_path, &child_path).unwrap(); + + // Append the new directory to our own PATH. + let path = { + let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect(); + paths.push(child_dir.to_path_buf()); + env::join_paths(paths).unwrap() + }; + + let child_output = process::Command::new("mytest").env("PATH", &path) + .arg("child") + .output().unwrap(); + + assert!(child_output.status.success(), + format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap())); +} diff --git a/src/test/ui-fulldeps/issue-15778-pass.rs b/src/test/ui-fulldeps/issue-15778-pass.rs new file mode 100644 index 00000000000..b93630d56b0 --- /dev/null +++ b/src/test/ui-fulldeps/issue-15778-pass.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:lint-for-crate-rpass.rs +// ignore-stage1 +// compile-flags: -D crate-not-okay + +#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)] + +#![plugin(lint_for_crate_rpass)] +#![rustc_crate_okay] +#![rustc_crate_blue] +#![rustc_crate_red] +#![rustc_crate_grey] +#![rustc_crate_green] + +fn main() {} diff --git a/src/test/ui-fulldeps/issue-15924.rs b/src/test/ui-fulldeps/issue-15924.rs new file mode 100644 index 00000000000..ec33de12ebb --- /dev/null +++ b/src/test/ui-fulldeps/issue-15924.rs @@ -0,0 +1,27 @@ +// run-pass + +#![allow(unused_imports)] +#![allow(unused_must_use)] +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +extern crate serialize; + +use std::fmt; +use serialize::{Encoder, Encodable}; +use serialize::json; + +struct Foo { + v: T, +} + +impl Drop for Foo { + fn drop(&mut self) { + json::encode(&self.v); + } +} + +fn main() { + let _ = Foo { v: 10 }; +} diff --git a/src/test/ui-fulldeps/issue-16822.rs b/src/test/ui-fulldeps/issue-16822.rs new file mode 100644 index 00000000000..c611c33affd --- /dev/null +++ b/src/test/ui-fulldeps/issue-16822.rs @@ -0,0 +1,22 @@ +// run-pass +// aux-build:issue-16822.rs + +extern crate issue_16822 as lib; + +use std::cell::RefCell; + +struct App { + i: isize +} + +impl lib::Update for App { + fn update(&mut self) { + self.i += 1; + } +} + +fn main(){ + let app = App { i: 5 }; + let window = lib::Window { data: RefCell::new(app) }; + window.update(1); +} diff --git a/src/test/ui-fulldeps/issue-18502.rs b/src/test/ui-fulldeps/issue-18502.rs new file mode 100644 index 00000000000..2082ae7a991 --- /dev/null +++ b/src/test/ui-fulldeps/issue-18502.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-18502.rs + +extern crate issue_18502 as fmt; + +fn main() { + ::fmt::baz(); +} diff --git a/src/test/ui-fulldeps/issue-24106.rs b/src/test/ui-fulldeps/issue-24106.rs new file mode 100644 index 00000000000..45f0bd5b679 --- /dev/null +++ b/src/test/ui-fulldeps/issue-24106.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-24106.rs + +extern crate issue_24106; + +fn main() { + issue_24106::go::<()>(); +} diff --git a/src/test/ui-fulldeps/issue-24972.rs b/src/test/ui-fulldeps/issue-24972.rs new file mode 100644 index 00000000000..0d354aac137 --- /dev/null +++ b/src/test/ui-fulldeps/issue-24972.rs @@ -0,0 +1,29 @@ +// run-pass + +#![allow(dead_code)] +#![feature(rustc_private)] + +extern crate serialize; + +use serialize::{Encodable, Decodable}; +use std::fmt::Display; + +pub trait Entity : Decodable + Encodable + Sized { + type Key: Clone + Decodable + Encodable + ToString + Display + Eq + Ord + Sized; + + fn id(&self) -> Self::Key; + + fn find_by_id(id: Self::Key) -> Option; +} + +pub struct DbRef { + pub id: E::Key, +} + +impl DbRef where E: Entity { + fn get(self) -> Option { + E::find_by_id(self.id) + } +} + +fn main() {} diff --git a/src/test/ui-fulldeps/issue-2804.rs b/src/test/ui-fulldeps/issue-2804.rs new file mode 100644 index 00000000000..a5345bbcd14 --- /dev/null +++ b/src/test/ui-fulldeps/issue-2804.rs @@ -0,0 +1,70 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![feature(rustc_private)] + +extern crate serialize; + +use std::collections::HashMap; +use serialize::json::{self, Json}; +use std::option; + +enum object { + bool_value(bool), + int_value(i64), +} + +fn lookup(table: json::Object, key: String, default: String) -> String +{ + match table.get(&key) { + option::Option::Some(&Json::String(ref s)) => { + s.to_string() + } + option::Option::Some(value) => { + println!("{} was expected to be a string but is a {}", key, value); + default + } + option::Option::None => { + default + } + } +} + +fn add_interface(_store: isize, managed_ip: String, data: json::Json) -> (String, object) +{ + match &data { + &Json::Object(ref interface) => { + let name = lookup(interface.clone(), + "ifDescr".to_string(), + "".to_string()); + let label = format!("{}-{}", managed_ip, name); + + (label, object::bool_value(false)) + } + _ => { + println!("Expected dict for {} interfaces, found {}", managed_ip, data); + ("gnos:missing-interface".to_string(), object::bool_value(true)) + } + } +} + +fn add_interfaces(store: isize, managed_ip: String, device: HashMap) +-> Vec<(String, object)> { + match device["interfaces"] { + Json::Array(ref interfaces) => + { + interfaces.iter().map(|interface| { + add_interface(store, managed_ip.clone(), (*interface).clone()) + }).collect() + } + _ => + { + println!("Expected list for {} interfaces, found {}", managed_ip, + device["interfaces"]); + Vec::new() + } + } +} + +pub fn main() {} diff --git a/src/test/ui-fulldeps/issue-40001.rs b/src/test/ui-fulldeps/issue-40001.rs new file mode 100644 index 00000000000..65e188ed1b6 --- /dev/null +++ b/src/test/ui-fulldeps/issue-40001.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-40001-plugin.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(issue_40001_plugin)] + +#[whitelisted_attr] +fn main() {} diff --git a/src/test/ui-fulldeps/issue-4016.rs b/src/test/ui-fulldeps/issue-4016.rs new file mode 100644 index 00000000000..fb84acbe645 --- /dev/null +++ b/src/test/ui-fulldeps/issue-4016.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(dead_code)] + +#![feature(rustc_private)] + +extern crate serialize; + +use serialize::{json, Decodable}; + +trait JD : Decodable {} + +fn exec() { + let doc = json::from_str("").unwrap(); + let mut decoder = json::Decoder::new(doc); + let _v: T = Decodable::decode(&mut decoder).unwrap(); + panic!() +} + +pub fn main() {} diff --git a/src/test/ui-fulldeps/issue-4036.rs b/src/test/ui-fulldeps/issue-4036.rs new file mode 100644 index 00000000000..9c9d3914268 --- /dev/null +++ b/src/test/ui-fulldeps/issue-4036.rs @@ -0,0 +1,17 @@ +// run-pass +// Issue #4036: Test for an issue that arose around fixing up type inference +// byproducts in vtable records. + +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +extern crate serialize; + +use serialize::{json, Decodable}; + +pub fn main() { + let json = json::from_str("[1]").unwrap(); + let mut decoder = json::Decoder::new(json); + let _x: Vec = Decodable::decode(&mut decoder).unwrap(); +} diff --git a/src/test/ui-fulldeps/linkage-visibility.rs b/src/test/ui-fulldeps/linkage-visibility.rs new file mode 100644 index 00000000000..ae46fbc4e8a --- /dev/null +++ b/src/test/ui-fulldeps/linkage-visibility.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:linkage-visibility.rs +// ignore-android: FIXME(#10356) +// ignore-windows: std::dynamic_lib does not work on Windows well +// ignore-emscripten no dynamic linking + +extern crate linkage_visibility as foo; + +pub fn main() { + foo::test(); + foo::foo2::(); + foo::foo(); +} diff --git a/src/test/ui-fulldeps/llvm-pass-plugin.rs b/src/test/ui-fulldeps/llvm-pass-plugin.rs new file mode 100644 index 00000000000..a9b53fa8c74 --- /dev/null +++ b/src/test/ui-fulldeps/llvm-pass-plugin.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:llvm-pass-plugin.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(llvm_pass_plugin)] + +pub fn main() { } diff --git a/src/test/ui-fulldeps/lto-syntax-extension.rs b/src/test/ui-fulldeps/lto-syntax-extension.rs new file mode 100644 index 00000000000..135861dd772 --- /dev/null +++ b/src/test/ui-fulldeps/lto-syntax-extension.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:lto-syntax-extension-lib.rs +// aux-build:lto-syntax-extension-plugin.rs +// compile-flags:-C lto +// ignore-stage1 +// no-prefer-dynamic + +#![feature(plugin)] +#![plugin(lto_syntax_extension_plugin)] + +extern crate lto_syntax_extension_lib; + +fn main() { + lto_syntax_extension_lib::foo(); +} diff --git a/src/test/ui-fulldeps/macro-crate-multi-decorator.rs b/src/test/ui-fulldeps/macro-crate-multi-decorator.rs new file mode 100644 index 00000000000..e396cf01615 --- /dev/null +++ b/src/test/ui-fulldeps/macro-crate-multi-decorator.rs @@ -0,0 +1,49 @@ +// run-pass + +#![allow(plugin_as_library)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +// aux-build:macro-crate-test.rs +// ignore-stage1 + +#![feature(rustc_attrs)] + +#[macro_use] +extern crate macro_crate_test; + +// The duplicate macro will create a copy of the item with the given identifier. + +#[rustc_duplicate(MyCopy)] +struct MyStruct { + number: i32 +} + +trait TestTrait { + #[rustc_duplicate(TestType2)] + type TestType; + + #[rustc_duplicate(required_fn2)] + fn required_fn(&self); + + #[rustc_duplicate(provided_fn2)] + fn provided_fn(&self) { } +} + +impl TestTrait for MyStruct { + #[rustc_duplicate(TestType2)] + type TestType = f64; + + #[rustc_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/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs new file mode 100644 index 00000000000..8631bcca6d2 --- /dev/null +++ b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -0,0 +1,29 @@ +// run-pass +// Testing that a libsyntax can parse modules with canonicalized base path +// ignore-cross-compile + +#![feature(rustc_private)] + +extern crate syntax; + +use std::path::Path; +use syntax::source_map::FilePathMapping; +use syntax::parse::{self, ParseSess}; + +#[path = "mod_dir_simple/test.rs"] +mod gravy; + +pub fn main() { + syntax::with_default_globals(|| parse()); + + assert_eq!(gravy::foo(), 10); +} + +fn parse() { + let parse_session = ParseSess::new(FilePathMapping::empty()); + + let path = Path::new(file!()); + let path = path.canonicalize().unwrap(); + let mut parser = parse::new_parser_from_file(&parse_session, &path); + let _ = parser.parse_crate_mod(); +} diff --git a/src/test/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir b/src/test/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui-fulldeps/mod_dir_simple/test.rs b/src/test/ui-fulldeps/mod_dir_simple/test.rs new file mode 100644 index 00000000000..35e26093a2d --- /dev/null +++ b/src/test/ui-fulldeps/mod_dir_simple/test.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() -> isize { 10 } diff --git a/src/test/ui-fulldeps/myriad-closures.rs b/src/test/ui-fulldeps/myriad-closures.rs new file mode 100644 index 00000000000..310351f50cb --- /dev/null +++ b/src/test/ui-fulldeps/myriad-closures.rs @@ -0,0 +1,39 @@ +// run-pass +// This test case tests whether we can handle code bases that contain a high +// number of closures, something that needs special handling in the MingGW +// toolchain. +// See https://github.com/rust-lang/rust/issues/34793 for more information. + +// Make sure we don't optimize anything away: +// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals + +// Expand something exponentially +macro_rules! go_bacterial { + ($mac:ident) => ($mac!()); + ($mac:ident 1 $($t:tt)*) => ( + go_bacterial!($mac $($t)*); + go_bacterial!($mac $($t)*); + ) +} + +macro_rules! mk_closure { + () => ((move || {})()) +} + +macro_rules! mk_fn { + () => { + { + fn function() { + // Make 16 closures + go_bacterial!(mk_closure 1 1 1 1); + } + let _ = function(); + } + } +} + +fn main() { + // Make 2^8 functions, each containing 16 closures, + // resulting in 2^12 closures overall. + go_bacterial!(mk_fn 1 1 1 1 1 1 1 1); +} diff --git a/src/test/ui-fulldeps/newtype_index.rs b/src/test/ui-fulldeps/newtype_index.rs new file mode 100644 index 00000000000..336b584768f --- /dev/null +++ b/src/test/ui-fulldeps/newtype_index.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(rustc_private)] + +extern crate rustc_data_structures; +extern crate serialize as rustc_serialize; + +use rustc_data_structures::{newtype_index, indexed_vec::Idx}; + +newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); + +use std::mem::size_of; + +fn main() { + assert_eq!(size_of::(), 4); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>>(), 4); + assert_eq!(size_of::>>>(), 4); + assert_eq!(size_of::>>>>(), 4); + assert_eq!(size_of::>>>>>(), 4); + assert_eq!(size_of::>>>>>>(), 8); +} diff --git a/src/test/ui-fulldeps/outlive-expansion-phase.rs b/src/test/ui-fulldeps/outlive-expansion-phase.rs new file mode 100644 index 00000000000..752f1da7377 --- /dev/null +++ b/src/test/ui-fulldeps/outlive-expansion-phase.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:outlive-expansion-phase.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(outlive_expansion_phase)] + +pub fn main() {} diff --git a/src/test/ui-fulldeps/plugin-args-1.rs b/src/test/ui-fulldeps/plugin-args-1.rs new file mode 100644 index 00000000000..d6437146775 --- /dev/null +++ b/src/test/ui-fulldeps/plugin-args-1.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:plugin-args.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(plugin_args)] + +fn main() { + assert_eq!(plugin_args!(), ""); +} diff --git a/src/test/ui-fulldeps/plugin-args-2.rs b/src/test/ui-fulldeps/plugin-args-2.rs new file mode 100644 index 00000000000..949f8440379 --- /dev/null +++ b/src/test/ui-fulldeps/plugin-args-2.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:plugin-args.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(plugin_args())] + +fn main() { + assert_eq!(plugin_args!(), ""); +} diff --git a/src/test/ui-fulldeps/plugin-args-3.rs b/src/test/ui-fulldeps/plugin-args-3.rs new file mode 100644 index 00000000000..efdbcd0bf0d --- /dev/null +++ b/src/test/ui-fulldeps/plugin-args-3.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:plugin-args.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(plugin_args(hello(there), how(are="you")))] + +fn main() { + assert_eq!(plugin_args!(), "hello(there), how(are = \"you\")"); +} diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs new file mode 100644 index 00000000000..09f58521e5d --- /dev/null +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -0,0 +1,230 @@ +// run-pass +// ignore-cross-compile + +// The general idea of this test is to enumerate all "interesting" expressions and check that +// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: +// +// 1. The test focuses on expression nesting, because interactions between different expression +// types are harder to test manually than single expression types in isolation. +// +// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + +// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct +// handling of an expression might depend on the expression's parent, but doesn't depend on its +// siblings or any more distant ancestors. +// +// 3. The test only checks certain expression kinds. The assumption is that similar expression +// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer +// and parser. So if all combinations of exprs involving `if` work correctly, then combinations +// using `while`, `if let`, and so on will likely work as well. + +#![feature(rustc_private)] + +extern crate rustc_data_structures; +extern crate syntax; + +use rustc_data_structures::thin_vec::ThinVec; +use syntax::ast::*; +use syntax::source_map::{Spanned, DUMMY_SP, FileName}; +use syntax::source_map::FilePathMapping; +use syntax::mut_visit::{self, MutVisitor, visit_clobber}; +use syntax::parse::{self, ParseSess}; +use syntax::print::pprust; +use syntax::ptr::P; + + +fn parse_expr(ps: &ParseSess, src: &str) -> P { + let src_as_string = src.to_string(); + + let mut p = parse::new_parser_from_source_str(ps, + FileName::Custom(src_as_string.clone()), + src_as_string); + p.parse_expr().unwrap() +} + + +// Helper functions for building exprs +fn expr(kind: ExprKind) -> P { + P(Expr { + id: DUMMY_NODE_ID, + node: kind, + span: DUMMY_SP, + attrs: ThinVec::new(), + }) +} + +fn make_x() -> P { + let seg = PathSegment::from_ident(Ident::from_str("x")); + let path = Path { segments: vec![seg], span: DUMMY_SP }; + expr(ExprKind::Path(None, path)) +} + +/// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting" +/// combinations of expression nesting. For example, we explore combinations using `if`, but not +/// `while` or `match`, since those should print and parse in much the same way as `if`. +fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { + if depth == 0 { + f(make_x()); + return; + } + + let mut g = |e| f(expr(e)); + + for kind in 0..=19 { + match kind { + 0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))), + 1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))), + 2 => { + let seg = PathSegment::from_ident(Ident::from_str("x")); + iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( + seg.clone(), vec![e, make_x()]))); + iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( + seg.clone(), vec![make_x(), e]))); + }, + 3..=8 => { + let op = Spanned { + span: DUMMY_SP, + node: match kind { + 3 => BinOpKind::Add, + 4 => BinOpKind::Mul, + 5 => BinOpKind::Shl, + 6 => BinOpKind::And, + 7 => BinOpKind::Or, + 8 => BinOpKind::Lt, + _ => unreachable!(), + } + }; + iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x()))); + iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e))); + }, + 9 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e))); + }, + 10 => { + let block = P(Block { + stmts: Vec::new(), + id: DUMMY_NODE_ID, + rules: BlockCheckMode::Default, + span: DUMMY_SP, + }); + iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None))); + }, + 11 => { + let decl = P(FnDecl { + inputs: vec![], + output: FunctionRetTy::Default(DUMMY_SP), + c_variadic: false, + }); + iter_exprs(depth - 1, &mut |e| g( + ExprKind::Closure(CaptureBy::Value, + IsAsync::NotAsync, + Movability::Movable, + decl.clone(), + e, + DUMMY_SP))); + }, + 12 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x()))); + iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e))); + }, + 13 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f")))); + }, + 14 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::Range( + Some(e), Some(make_x()), RangeLimits::HalfOpen))); + iter_exprs(depth - 1, &mut |e| g(ExprKind::Range( + Some(make_x()), Some(e), RangeLimits::HalfOpen))); + }, + 15 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::AddrOf(Mutability::Immutable, e))); + }, + 16 => { + g(ExprKind::Ret(None)); + iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e)))); + }, + 17 => { + let path = Path::from_ident(Ident::from_str("S")); + g(ExprKind::Struct(path, vec![], Some(make_x()))); + }, + 18 => { + iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e))); + }, + 19 => { + let ps = vec![P(Pat { + id: DUMMY_NODE_ID, + node: PatKind::Wild, + span: DUMMY_SP, + })]; + iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(ps.clone(), e))) + }, + _ => panic!("bad counter value in iter_exprs"), + } + } +} + + +// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. + +/// `MutVisitor` that removes all `ExprKind::Paren` nodes. +struct RemoveParens; + +impl MutVisitor for RemoveParens { + fn visit_expr(&mut self, e: &mut P) { + match e.node.clone() { + ExprKind::Paren(inner) => *e = inner, + _ => {} + }; + mut_visit::noop_visit_expr(e, self); + } +} + + +/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`. +struct AddParens; + +impl MutVisitor for AddParens { + fn visit_expr(&mut self, e: &mut P) { + mut_visit::noop_visit_expr(e, self); + visit_clobber(e, |e| { + P(Expr { + id: DUMMY_NODE_ID, + node: ExprKind::Paren(e), + span: DUMMY_SP, + attrs: ThinVec::new(), + }) + }); + } +} + +fn main() { + syntax::with_default_globals(|| run()); +} + +fn run() { + let ps = ParseSess::new(FilePathMapping::empty()); + + iter_exprs(2, &mut |mut e| { + // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, + // modulo placement of `Paren` nodes. + let printed = pprust::expr_to_string(&e); + println!("printed: {}", printed); + + let mut parsed = parse_expr(&ps, &printed); + + // We want to know if `parsed` is structurally identical to `e`, ignoring trivial + // differences like placement of `Paren`s or the exact ranges of node spans. + // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s + // everywhere we can, then pretty-print. This should give an unambiguous representation of + // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't + // relying on the correctness of the very thing we're testing. + RemoveParens.visit_expr(&mut e); + AddParens.visit_expr(&mut e); + let text1 = pprust::expr_to_string(&e); + RemoveParens.visit_expr(&mut parsed); + AddParens.visit_expr(&mut parsed); + let text2 = pprust::expr_to_string(&parsed); + assert!(text1 == text2, + "exprs are not equal:\n e = {:?}\n parsed = {:?}", + text1, text2); + }); +} diff --git a/src/test/ui-fulldeps/regions-mock-tcx.rs b/src/test/ui-fulldeps/regions-mock-tcx.rs new file mode 100644 index 00000000000..524c94a8555 --- /dev/null +++ b/src/test/ui-fulldeps/regions-mock-tcx.rs @@ -0,0 +1,134 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_imports)] + +// Test a sample usage pattern for regions. Makes use of the +// following features: +// +// - Multiple lifetime parameters +// - Arenas + +#![feature(rustc_private, libc)] + +extern crate arena; +extern crate libc; + +use TypeStructure::{TypeInt, TypeFunction}; +use AstKind::{ExprInt, ExprVar, ExprLambda}; +use arena::TypedArena; +use std::collections::HashMap; +use std::mem; + +type Type<'tcx> = &'tcx TypeStructure<'tcx>; + +#[derive(Copy, Clone, Debug)] +enum TypeStructure<'tcx> { + TypeInt, + TypeFunction(Type<'tcx>, Type<'tcx>), +} + +impl<'tcx> PartialEq for TypeStructure<'tcx> { + fn eq(&self, other: &TypeStructure<'tcx>) -> bool { + match (*self, *other) { + (TypeInt, TypeInt) => true, + (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b, + _ => false + } + } +} + +impl<'tcx> Eq for TypeStructure<'tcx> {} + +type TyArena<'tcx> = TypedArena>; +type AstArena<'ast> = TypedArena>; + +struct TypeContext<'tcx, 'ast> { + ty_arena: &'tcx TyArena<'tcx>, + types: Vec> , + type_table: HashMap>, + + ast_arena: &'ast AstArena<'ast>, + ast_counter: usize, +} + +impl<'tcx,'ast> TypeContext<'tcx, 'ast> { + fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>) + -> TypeContext<'tcx, 'ast> { + TypeContext { ty_arena: ty_arena, + types: Vec::new(), + type_table: HashMap::new(), + + ast_arena: ast_arena, + ast_counter: 0 } + } + + fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> { + for &ty in &self.types { + if *ty == s { + return ty; + } + } + + let ty = self.ty_arena.alloc(s); + self.types.push(ty); + ty + } + + fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> { + self.type_table.insert(id, ty); + ty + } + + fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> { + let id = self.ast_counter; + self.ast_counter += 1; + self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a }) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +struct NodeId { + id: usize +} + +type Ast<'ast> = &'ast AstStructure<'ast>; + +#[derive(Copy, Clone)] +struct AstStructure<'ast> { + id: NodeId, + kind: AstKind<'ast> +} + +#[derive(Copy, Clone)] +enum AstKind<'ast> { + ExprInt, + ExprVar(usize), + ExprLambda(Ast<'ast>), +} + +fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>, + ast: Ast<'ast>) -> Type<'tcx> +{ + match ast.kind { + ExprInt | ExprVar(_) => { + let ty = tcx.add_type(TypeInt); + tcx.set_type(ast.id, ty) + } + ExprLambda(ast) => { + let arg_ty = tcx.add_type(TypeInt); + let body_ty = compute_types(tcx, ast); + let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty)); + tcx.set_type(ast.id, lambda_ty) + } + } +} + +pub fn main() { + let ty_arena = TypedArena::default(); + let ast_arena = TypedArena::default(); + let mut tcx = TypeContext::new(&ty_arena, &ast_arena); + let ast = tcx.ast(ExprInt); + let ty = compute_types(&mut tcx, ast); + assert_eq!(*ty, TypeInt); +} diff --git a/src/test/ui-fulldeps/rename-directory.rs b/src/test/ui-fulldeps/rename-directory.rs new file mode 100644 index 00000000000..8fc340cb918 --- /dev/null +++ b/src/test/ui-fulldeps/rename-directory.rs @@ -0,0 +1,30 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unused_imports)] +// This test can't be a unit test in std, +// because it needs TempDir, which is in extra + +// ignore-cross-compile + +use std::env; +use std::ffi::CString; +use std::fs::{self, File}; +use std::path::PathBuf; + +fn rename_directory() { + let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); + let old_path = tmpdir.join("foo/bar/baz"); + fs::create_dir_all(&old_path).unwrap(); + let test_file = &old_path.join("temp.txt"); + + File::create(test_file).unwrap(); + + let new_path = tmpdir.join("quux/blat"); + fs::create_dir_all(&new_path).unwrap(); + fs::rename(&old_path, &new_path.join("newdir")); + assert!(new_path.join("newdir").is_dir()); + assert!(new_path.join("newdir/temp.txt").exists()); +} + +pub fn main() { rename_directory() } diff --git a/src/test/ui-fulldeps/roman-numerals-macro.rs b/src/test/ui-fulldeps/roman-numerals-macro.rs new file mode 100644 index 00000000000..5c4ba3158db --- /dev/null +++ b/src/test/ui-fulldeps/roman-numerals-macro.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:roman-numerals.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(roman_numerals)] + +pub fn main() { + assert_eq!(rn!(MMXV), 2015); + assert_eq!(rn!(MCMXCIX), 1999); + assert_eq!(rn!(XXV), 25); + assert_eq!(rn!(MDCLXVI), 1666); + assert_eq!(rn!(MMMDCCCLXXXVIII), 3888); + assert_eq!(rn!(MMXIV), 2014); +} diff --git a/src/test/ui-fulldeps/rustc_encodable_hygiene.rs b/src/test/ui-fulldeps/rustc_encodable_hygiene.rs new file mode 100644 index 00000000000..42a6153465c --- /dev/null +++ b/src/test/ui-fulldeps/rustc_encodable_hygiene.rs @@ -0,0 +1,24 @@ +// run-pass + +#![feature(rustc_private)] + +#[allow(dead_code)] + +extern crate serialize as rustc_serialize; + +#[derive(RustcDecodable, RustcEncodable,Debug)] +struct A { + a: String, +} + +trait Trait { + fn encode(&self); +} + +impl Trait for T { + fn encode(&self) { + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/ui-fulldeps/stdio-from.rs b/src/test/ui-fulldeps/stdio-from.rs new file mode 100644 index 00000000000..fef9f27fcdf --- /dev/null +++ b/src/test/ui-fulldeps/stdio-from.rs @@ -0,0 +1,69 @@ +// run-pass +// ignore-cross-compile + +use std::env; +use std::fs::File; +use std::io; +use std::io::{Read, Write}; +use std::process::{Command, Stdio}; +use std::path::PathBuf; + +fn main() { + if env::args().len() > 1 { + child().unwrap() + } else { + parent().unwrap() + } +} + +fn parent() -> io::Result<()> { + let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); + let input = td.join("stdio-from-input"); + let output = td.join("stdio-from-output"); + + File::create(&input)?.write_all(b"foo\n")?; + + // Set up this chain: + // $ me file + // ... to duplicate each line 8 times total. + + let mut child1 = Command::new(env::current_exe()?) + .arg("first") + .stdin(File::open(&input)?) // tests File::into() + .stdout(Stdio::piped()) + .spawn()?; + + let mut child3 = Command::new(env::current_exe()?) + .arg("third") + .stdin(Stdio::piped()) + .stdout(File::create(&output)?) // tests File::into() + .spawn()?; + + // Started out of order so we can test both `ChildStdin` and `ChildStdout`. + let mut child2 = Command::new(env::current_exe()?) + .arg("second") + .stdin(child1.stdout.take().unwrap()) // tests ChildStdout::into() + .stdout(child3.stdin.take().unwrap()) // tests ChildStdin::into() + .spawn()?; + + assert!(child1.wait()?.success()); + assert!(child2.wait()?.success()); + assert!(child3.wait()?.success()); + + let mut data = String::new(); + File::open(&output)?.read_to_string(&mut data)?; + for line in data.lines() { + assert_eq!(line, "foo"); + } + assert_eq!(data.lines().count(), 8); + Ok(()) +} + +fn child() -> io::Result<()> { + // double everything + let mut input = vec![]; + io::stdin().read_to_end(&mut input)?; + io::stdout().write_all(&input)?; + io::stdout().write_all(&input)?; + Ok(()) +} diff --git a/src/test/ui-fulldeps/switch-stdout.rs b/src/test/ui-fulldeps/switch-stdout.rs new file mode 100644 index 00000000000..e105637c3da --- /dev/null +++ b/src/test/ui-fulldeps/switch-stdout.rs @@ -0,0 +1,52 @@ +// run-pass + +use std::env; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::PathBuf; + +#[cfg(unix)] +fn switch_stdout_to(file: File) { + use std::os::unix::prelude::*; + + extern { + fn dup2(old: i32, new: i32) -> i32; + } + + unsafe { + assert_eq!(dup2(file.as_raw_fd(), 1), 1); + } +} + +#[cfg(windows)] +fn switch_stdout_to(file: File) { + use std::os::windows::prelude::*; + + extern "system" { + fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32; + } + + const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32; + + unsafe { + let rc = SetStdHandle(STD_OUTPUT_HANDLE, + file.into_raw_handle() as *mut _); + assert!(rc != 0); + } +} + +fn main() { + let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); + let path = path.join("switch-stdout-output"); + let f = File::create(&path).unwrap(); + + println!("foo"); + std::io::stdout().flush().unwrap(); + switch_stdout_to(f); + println!("bar"); + std::io::stdout().flush().unwrap(); + + let mut contents = String::new(); + File::open(&path).unwrap().read_to_string(&mut contents).unwrap(); + assert_eq!(contents, "bar\n"); +} diff --git a/src/test/ui-fulldeps/undef_mask.rs b/src/test/ui-fulldeps/undef_mask.rs new file mode 100644 index 00000000000..0caccad6229 --- /dev/null +++ b/src/test/ui-fulldeps/undef_mask.rs @@ -0,0 +1,27 @@ +// run-pass +// ignore-cross-compile +// ignore-stage1 + +#![feature(rustc_private)] + +extern crate rustc; + +use rustc::mir::interpret::UndefMask; +use rustc::ty::layout::Size; + +fn main() { + let mut mask = UndefMask::new(Size::from_bytes(500), false); + assert!(!mask.get(Size::from_bytes(499))); + mask.set(Size::from_bytes(499), true); + assert!(mask.get(Size::from_bytes(499))); + mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true); + for i in 0..100 { + assert!(!mask.get(Size::from_bytes(i))); + } + for i in 100..256 { + assert!(mask.get(Size::from_bytes(i))); + } + for i in 256..499 { + assert!(!mask.get(Size::from_bytes(i))); + } +} diff --git a/src/test/ui/abi-sysv64-arg-passing.rs b/src/test/ui/abi-sysv64-arg-passing.rs new file mode 100644 index 00000000000..d40006eb9b6 --- /dev/null +++ b/src/test/ui/abi-sysv64-arg-passing.rs @@ -0,0 +1,367 @@ +// 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 } + + #[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 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(); + } +} + +#[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(); +} + +#[cfg(not(target_arch = "x86_64"))] +fn main() { + +} diff --git a/src/test/ui/abi-sysv64-register-usage.rs b/src/test/ui/abi-sysv64-register-usage.rs new file mode 100644 index 00000000000..0c7e2d906b7 --- /dev/null +++ b/src/test/ui/abi-sysv64-register-usage.rs @@ -0,0 +1,96 @@ +// 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(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)] +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 { + 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/src/test/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/src/test/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs new file mode 100644 index 00000000000..df819306e4a --- /dev/null +++ b/src/test/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/abort-on-c-abi.rs b/src/test/ui/abort-on-c-abi.rs new file mode 100644 index 00000000000..cd7dd1b6a45 --- /dev/null +++ b/src/test/ui/abort-on-c-abi.rs @@ -0,0 +1,38 @@ +// run-pass + +#![allow(unused_must_use)] +// 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}; + +extern "C" fn panic_in_ffi() { + panic!("Test"); +} + +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 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(); + assert!(!p.wait().unwrap().success()); +} diff --git a/src/test/ui/alias-uninit-value.rs b/src/test/ui/alias-uninit-value.rs new file mode 100644 index 00000000000..932c93245e6 --- /dev/null +++ b/src/test/ui/alias-uninit-value.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/align-with-extern-c-fn.rs new file mode 100644 index 00000000000..09abe4fbf7e --- /dev/null +++ b/src/test/ui/align-with-extern-c-fn.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(stable_features)] +#![allow(unused_variables)] + +// #45662 + +#![feature(repr_align)] + +#[repr(align(16))] +pub struct A(i64); + +pub extern "C" fn foo(x: A) {} + +fn main() { + foo(A(0)); +} diff --git a/src/test/ui/alignment-gep-tup-like-1.rs b/src/test/ui/alignment-gep-tup-like-1.rs new file mode 100644 index 00000000000..c51c56b0899 --- /dev/null +++ b/src/test/ui/alignment-gep-tup-like-1.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/alloca-from-derived-tydesc.rs b/src/test/ui/alloca-from-derived-tydesc.rs new file mode 100644 index 00000000000..c7f7fbad435 --- /dev/null +++ b/src/test/ui/alloca-from-derived-tydesc.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/allocator-alloc-one.rs b/src/test/ui/allocator-alloc-one.rs new file mode 100644 index 00000000000..312d5f13b1a --- /dev/null +++ b/src/test/ui/allocator-alloc-one.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(stable_features)] + +#![feature(allocator_api, nonnull)] + +use std::alloc::{Alloc, Global, Layout, handle_alloc_error}; + +fn main() { + unsafe { + let ptr = Global.alloc_one::().unwrap_or_else(|_| { + handle_alloc_error(Layout::new::()) + }); + *ptr.as_ptr() = 4; + assert_eq!(*ptr.as_ptr(), 4); + Global.dealloc_one(ptr); + } +} diff --git a/src/test/ui/allocator/auxiliary/custom-as-global.rs b/src/test/ui/allocator/auxiliary/custom-as-global.rs new file mode 100644 index 00000000000..a5e96e77501 --- /dev/null +++ b/src/test/ui/allocator/auxiliary/custom-as-global.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/allocator/auxiliary/custom.rs b/src/test/ui/allocator/auxiliary/custom.rs new file mode 100644 index 00000000000..b0ec9ab0929 --- /dev/null +++ b/src/test/ui/allocator/auxiliary/custom.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/allocator/auxiliary/helper.rs b/src/test/ui/allocator/auxiliary/helper.rs new file mode 100644 index 00000000000..7f6770c226a --- /dev/null +++ b/src/test/ui/allocator/auxiliary/helper.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +use std::fmt; + +pub fn work_with(p: &fmt::Debug) { + drop(p); +} diff --git a/src/test/ui/allocator/custom-in-block.rs b/src/test/ui/allocator/custom-in-block.rs new file mode 100644 index 00000000000..12813a1fc8b --- /dev/null +++ b/src/test/ui/allocator/custom-in-block.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/allocator/custom-in-submodule.rs b/src/test/ui/allocator/custom-in-submodule.rs new file mode 100644 index 00000000000..ea341b1ac14 --- /dev/null +++ b/src/test/ui/allocator/custom-in-submodule.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/allocator/custom.rs b/src/test/ui/allocator/custom.rs new file mode 100644 index 00000000000..71f72ae46c2 --- /dev/null +++ b/src/test/ui/allocator/custom.rs @@ -0,0 +1,58 @@ +// run-pass + +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate helper; + +use std::alloc::{self, Global, Alloc, System, Layout}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +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); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + HITS.fetch_add(1, Ordering::SeqCst); + System.dealloc(ptr, 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 ptr = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&ptr); + assert_eq!(HITS.load(Ordering::SeqCst), n + 1); + Global.dealloc(ptr, layout.clone()); + 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 ptr = System.alloc(layout.clone()).unwrap(); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + helper::work_with(&ptr); + System.dealloc(ptr, layout); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + } +} diff --git a/src/test/ui/allocator/xcrate-use.rs b/src/test/ui/allocator/xcrate-use.rs new file mode 100644 index 00000000000..039c70e77be --- /dev/null +++ b/src/test/ui/allocator/xcrate-use.rs @@ -0,0 +1,35 @@ +// run-pass + +// aux-build:custom.rs +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate custom; +extern crate helper; + +use std::alloc::{Global, Alloc, System, Layout}; +use std::sync::atomic::{Ordering, AtomicUsize}; + +#[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 ptr = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&ptr); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); + Global.dealloc(ptr, layout.clone()); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + + let ptr = System.alloc(layout.clone()).unwrap(); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + helper::work_with(&ptr); + System.dealloc(ptr, layout); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + } +} diff --git a/src/test/ui/allocator/xcrate-use2.rs b/src/test/ui/allocator/xcrate-use2.rs new file mode 100644 index 00000000000..d8478fb5eaa --- /dev/null +++ b/src/test/ui/allocator/xcrate-use2.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/anon-extern-mod.rs b/src/test/ui/anon-extern-mod.rs new file mode 100644 index 00000000000..37a67876c91 --- /dev/null +++ b/src/test/ui/anon-extern-mod.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/argument-passing.rs b/src/test/ui/argument-passing.rs new file mode 100644 index 00000000000..74759a4a6bd --- /dev/null +++ b/src/test/ui/argument-passing.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/array-slice-vec/arr_cycle.rs b/src/test/ui/array-slice-vec/arr_cycle.rs new file mode 100644 index 00000000000..c262b5a1ff0 --- /dev/null +++ b/src/test/ui/array-slice-vec/arr_cycle.rs @@ -0,0 +1,31 @@ +// 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 (b1, b2, b3); + b1 = B::new(); + b2 = B::new(); + b3 = B::new(); + b1.a[0].set(Some(&b2)); + b1.a[1].set(Some(&b3)); + b2.a[0].set(Some(&b2)); + b2.a[1].set(Some(&b3)); + b3.a[0].set(Some(&b1)); + b3.a[1].set(Some(&b2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/array-slice-vec/array_const_index-1.rs b/src/test/ui/array-slice-vec/array_const_index-1.rs new file mode 100644 index 00000000000..8ee225f5cdf --- /dev/null +++ b/src/test/ui/array-slice-vec/array_const_index-1.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs new file mode 100644 index 00000000000..d4858932815 --- /dev/null +++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs new file mode 100644 index 00000000000..e8a5b00a55b --- /dev/null +++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/array-slice-vec/cast-in-array-size.rs b/src/test/ui/array-slice-vec/cast-in-array-size.rs new file mode 100644 index 00000000000..b112dcaef3e --- /dev/null +++ b/src/test/ui/array-slice-vec/cast-in-array-size.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/array-slice-vec/check-static-mut-slices.rs b/src/test/ui/array-slice-vec/check-static-mut-slices.rs new file mode 100644 index 00000000000..b89c634036e --- /dev/null +++ b/src/test/ui/array-slice-vec/check-static-mut-slices.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/array-slice-vec/check-static-slice.rs b/src/test/ui/array-slice-vec/check-static-slice.rs new file mode 100644 index 00000000000..1c607d13426 --- /dev/null +++ b/src/test/ui/array-slice-vec/check-static-slice.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/array-slice-vec/copy-out-of-array-1.rs b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs new file mode 100644 index 00000000000..e64985ae3f6 --- /dev/null +++ b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/array-slice-vec/destructure-array-1.rs b/src/test/ui/array-slice-vec/destructure-array-1.rs new file mode 100644 index 00000000000..74d893ee5b2 --- /dev/null +++ b/src/test/ui/array-slice-vec/destructure-array-1.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/array-slice-vec/empty-mutable-vec.rs b/src/test/ui/array-slice-vec/empty-mutable-vec.rs new file mode 100644 index 00000000000..91ab280b9c7 --- /dev/null +++ b/src/test/ui/array-slice-vec/empty-mutable-vec.rs @@ -0,0 +1,8 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +#![allow(unused_mut)] + + +pub fn main() { let mut _v: Vec = Vec::new(); } diff --git a/src/test/ui/array-slice-vec/estr-slice.rs b/src/test/ui/array-slice-vec/estr-slice.rs new file mode 100644 index 00000000000..cd2c1722065 --- /dev/null +++ b/src/test/ui/array-slice-vec/estr-slice.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/array-slice-vec/evec-slice.rs b/src/test/ui/array-slice-vec/evec-slice.rs new file mode 100644 index 00000000000..4bdf2dbdd6e --- /dev/null +++ b/src/test/ui/array-slice-vec/evec-slice.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/array-slice-vec/fixed_length_copy.rs b/src/test/ui/array-slice-vec/fixed_length_copy.rs new file mode 100644 index 00000000000..f73173e8484 --- /dev/null +++ b/src/test/ui/array-slice-vec/fixed_length_copy.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/array-slice-vec/huge-largest-array.rs b/src/test/ui/array-slice-vec/huge-largest-array.rs new file mode 100644 index 00000000000..9e78162c813 --- /dev/null +++ b/src/test/ui/array-slice-vec/huge-largest-array.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/array-slice-vec/ivec-pass-by-value.rs b/src/test/ui/array-slice-vec/ivec-pass-by-value.rs new file mode 100644 index 00000000000..e22aef96330 --- /dev/null +++ b/src/test/ui/array-slice-vec/ivec-pass-by-value.rs @@ -0,0 +1,4 @@ +// run-pass + +fn f(_a: Vec ) { } +pub fn main() { f(vec![1, 2, 3, 4, 5]); } diff --git a/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs b/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs new file mode 100644 index 00000000000..7afb9d8461f --- /dev/null +++ b/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/array-slice-vec/mutable-alias-vec.rs b/src/test/ui/array-slice-vec/mutable-alias-vec.rs new file mode 100644 index 00000000000..98dd46824fa --- /dev/null +++ b/src/test/ui/array-slice-vec/mutable-alias-vec.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/array-slice-vec/nested-vec-1.rs b/src/test/ui/array-slice-vec/nested-vec-1.rs new file mode 100644 index 00000000000..02a3ccf46f2 --- /dev/null +++ b/src/test/ui/array-slice-vec/nested-vec-1.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/array-slice-vec/nested-vec-2.rs b/src/test/ui/array-slice-vec/nested-vec-2.rs new file mode 100644 index 00000000000..d4a704d767e --- /dev/null +++ b/src/test/ui/array-slice-vec/nested-vec-2.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/array-slice-vec/nested-vec-3.rs b/src/test/ui/array-slice-vec/nested-vec-3.rs new file mode 100644 index 00000000000..52b892dbcdf --- /dev/null +++ b/src/test/ui/array-slice-vec/nested-vec-3.rs @@ -0,0 +1,54 @@ +// 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/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs b/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs new file mode 100644 index 00000000000..454f94be876 --- /dev/null +++ b/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs @@ -0,0 +1,7 @@ +// run-pass + +static FOO: [isize; 3] = [1, 2, 3]; + +pub fn main() { + println!("{} {} {}", FOO[0], FOO[1], FOO[2]); +} diff --git a/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs b/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs new file mode 100644 index 00000000000..17cf7e335b9 --- /dev/null +++ b/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/array-slice-vec/repeated-vector-syntax.rs b/src/test/ui/array-slice-vec/repeated-vector-syntax.rs new file mode 100644 index 00000000000..4458eb06dd5 --- /dev/null +++ b/src/test/ui/array-slice-vec/repeated-vector-syntax.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/array-slice-vec/show-boxed-slice.rs b/src/test/ui/array-slice-vec/show-boxed-slice.rs new file mode 100644 index 00000000000..dfa4c720bb0 --- /dev/null +++ b/src/test/ui/array-slice-vec/show-boxed-slice.rs @@ -0,0 +1,8 @@ +// run-pass + +#[derive(Debug)] +struct Foo(Box<[u8]>); + +pub fn main() { + println!("{:?}", Foo(Box::new([0, 1, 2]))); +} diff --git a/src/test/ui/array-slice-vec/slice-2.rs b/src/test/ui/array-slice-vec/slice-2.rs new file mode 100644 index 00000000000..01733f48234 --- /dev/null +++ b/src/test/ui/array-slice-vec/slice-2.rs @@ -0,0 +1,62 @@ +// run-pass + +// Test slicing expressions on slices and Vecs. + + +fn main() { + let x: &[isize] = &[1, 2, 3, 4, 5]; + let cmp: &[isize] = &[1, 2, 3, 4, 5]; + assert_eq!(&x[..], cmp); + let cmp: &[isize] = &[3, 4, 5]; + assert_eq!(&x[2..], cmp); + let cmp: &[isize] = &[1, 2, 3]; + assert_eq!(&x[..3], cmp); + let cmp: &[isize] = &[2, 3, 4]; + assert_eq!(&x[1..4], cmp); + + let x: Vec = vec![1, 2, 3, 4, 5]; + let cmp: &[isize] = &[1, 2, 3, 4, 5]; + assert_eq!(&x[..], cmp); + let cmp: &[isize] = &[3, 4, 5]; + assert_eq!(&x[2..], cmp); + let cmp: &[isize] = &[1, 2, 3]; + assert_eq!(&x[..3], cmp); + let cmp: &[isize] = &[2, 3, 4]; + assert_eq!(&x[1..4], cmp); + + let x: &mut [isize] = &mut [1, 2, 3, 4, 5]; + { + let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; + assert_eq!(&mut x[..], cmp); + } + { + let cmp: &mut [isize] = &mut [3, 4, 5]; + assert_eq!(&mut x[2..], cmp); + } + { + let cmp: &mut [isize] = &mut [1, 2, 3]; + assert_eq!(&mut x[..3], cmp); + } + { + let cmp: &mut [isize] = &mut [2, 3, 4]; + assert_eq!(&mut x[1..4], cmp); + } + + let mut x: Vec = vec![1, 2, 3, 4, 5]; + { + let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; + assert_eq!(&mut x[..], cmp); + } + { + let cmp: &mut [isize] = &mut [3, 4, 5]; + assert_eq!(&mut x[2..], cmp); + } + { + let cmp: &mut [isize] = &mut [1, 2, 3]; + assert_eq!(&mut x[..3], cmp); + } + { + let cmp: &mut [isize] = &mut [2, 3, 4]; + assert_eq!(&mut x[1..4], cmp); + } +} diff --git a/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs b/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs new file mode 100644 index 00000000000..83b08a3db4c --- /dev/null +++ b/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/array-slice-vec/slice-panic-1.rs b/src/test/ui/array-slice-vec/slice-panic-1.rs new file mode 100644 index 00000000000..8b27d055e2b --- /dev/null +++ b/src/test/ui/array-slice-vec/slice-panic-1.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/array-slice-vec/slice-panic-2.rs b/src/test/ui/array-slice-vec/slice-panic-2.rs new file mode 100644 index 00000000000..2ee564cadb3 --- /dev/null +++ b/src/test/ui/array-slice-vec/slice-panic-2.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/array-slice-vec/slice.rs b/src/test/ui/array-slice-vec/slice.rs new file mode 100644 index 00000000000..14e1ddf52eb --- /dev/null +++ b/src/test/ui/array-slice-vec/slice.rs @@ -0,0 +1,81 @@ +// 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/src/test/ui/array-slice-vec/slice_binary_search.rs b/src/test/ui/array-slice-vec/slice_binary_search.rs new file mode 100644 index 00000000000..12236960179 --- /dev/null +++ b/src/test/ui/array-slice-vec/slice_binary_search.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/array-slice-vec/variance-vec-covariant.rs b/src/test/ui/array-slice-vec/variance-vec-covariant.rs new file mode 100644 index 00000000000..d7e64132f89 --- /dev/null +++ b/src/test/ui/array-slice-vec/variance-vec-covariant.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/array-slice-vec/vec-concat.rs b/src/test/ui/array-slice-vec/vec-concat.rs new file mode 100644 index 00000000000..1f493679b79 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-concat.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::vec; + +pub fn main() { + let a: Vec = vec![1, 2, 3, 4, 5]; + let b: Vec = vec![6, 7, 8, 9, 0]; + let mut v: Vec = a; + v.extend_from_slice(&b); + println!("{}", v[9]); + assert_eq!(v[0], 1); + assert_eq!(v[7], 8); + assert_eq!(v[9], 0); +} diff --git a/src/test/ui/array-slice-vec/vec-dst.rs b/src/test/ui/array-slice-vec/vec-dst.rs new file mode 100644 index 00000000000..e741201652b --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-dst.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/array-slice-vec/vec-fixed-length.rs b/src/test/ui/array-slice-vec/vec-fixed-length.rs new file mode 100644 index 00000000000..5db02ee066b --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-fixed-length.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/array-slice-vec/vec-growth.rs b/src/test/ui/array-slice-vec/vec-growth.rs new file mode 100644 index 00000000000..b09f08bb85a --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-growth.rs @@ -0,0 +1,16 @@ +// run-pass + + + +pub fn main() { + let mut v = vec![1]; + v.push(2); + v.push(3); + v.push(4); + v.push(5); + assert_eq!(v[0], 1); + assert_eq!(v[1], 2); + assert_eq!(v[2], 3); + assert_eq!(v[3], 4); + assert_eq!(v[4], 5); +} diff --git a/src/test/ui/array-slice-vec/vec-late-init.rs b/src/test/ui/array-slice-vec/vec-late-init.rs new file mode 100644 index 00000000000..5dee3608256 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-late-init.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/array-slice-vec/vec-macro-no-std.rs b/src/test/ui/array-slice-vec/vec-macro-no-std.rs new file mode 100644 index 00000000000..443895f7c48 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-macro-no-std.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/array-slice-vec/vec-macro-repeat.rs b/src/test/ui/array-slice-vec/vec-macro-repeat.rs new file mode 100644 index 00000000000..7be8dadbe17 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-macro-repeat.rs @@ -0,0 +1,15 @@ +// run-pass + + + +pub fn main() { + assert_eq!(vec![1; 3], vec![1, 1, 1]); + assert_eq!(vec![1; 2], vec![1, 1]); + assert_eq!(vec![1; 1], vec![1]); + assert_eq!(vec![1; 0], vec![]); + + // from_elem syntax (see RFC 832) + let el = Box::new(1); + let n = 3; + assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); +} diff --git a/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs b/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs new file mode 100644 index 00000000000..bde01037181 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs b/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs new file mode 100644 index 00000000000..6c95bd50007 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs b/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs new file mode 100644 index 00000000000..f7a51f9c456 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs @@ -0,0 +1,8 @@ +// run-pass + + + +pub fn main() { + assert_eq!(vec![1], vec![1,]); + assert_eq!(vec![1, 2, 3], vec![1, 2, 3,]); +} diff --git a/src/test/ui/array-slice-vec/vec-matching-autoslice.rs b/src/test/ui/array-slice-vec/vec-matching-autoslice.rs new file mode 100644 index 00000000000..8179edf420c --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-matching-autoslice.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/array-slice-vec/vec-matching-fixed.rs b/src/test/ui/array-slice-vec/vec-matching-fixed.rs new file mode 100644 index 00000000000..5253bc1b214 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-matching-fixed.rs @@ -0,0 +1,32 @@ +// run-pass + +#![feature(slice_patterns)] + +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/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs new file mode 100644 index 00000000000..2b19c49c427 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs @@ -0,0 +1,48 @@ +// run-pass + +#![feature(slice_patterns)] + +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/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs new file mode 100644 index 00000000000..bce03b3375e --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_variables)] + +#![feature(slice_patterns)] + +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/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs new file mode 100644 index 00000000000..a37c25160fa --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-matching.rs @@ -0,0 +1,159 @@ +// run-pass + +#![feature(slice_patterns)] + +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); +} + +fn f() { + let x = &[1, 2, 3, 4, 5]; + let [a, [b, [c, ..].., d].., e] = *x; + assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); + + let x: &[isize] = x; + let (a, b, c, d, e) = match *x { + [a, [b, [c, ..].., d].., e] => (a, b, c, d, e), + _ => unimplemented!() + }; + + assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); +} + +pub fn main() { + a(); + b(); + b_slice(); + c(); + d(); + e(); + f(); +} diff --git a/src/test/ui/array-slice-vec/vec-push.rs b/src/test/ui/array-slice-vec/vec-push.rs new file mode 100644 index 00000000000..466ab3fab1c --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-push.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn main() { let mut v = vec![1, 2, 3]; v.push(1); } diff --git a/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs b/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs new file mode 100644 index 00000000000..3e0e18873ab --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs @@ -0,0 +1,5 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +pub fn main() { let _a = [0; 1 as usize]; } diff --git a/src/test/ui/array-slice-vec/vec-slice-drop.rs b/src/test/ui/array-slice-vec/vec-slice-drop.rs new file mode 100644 index 00000000000..3a9ea86af34 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-slice-drop.rs @@ -0,0 +1,31 @@ +// run-pass + +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +// Make sure that destructors get run on slice literals +struct foo<'a> { + x: &'a Cell, +} + +impl<'a> Drop for foo<'a> { + fn drop(&mut self) { + self.x.set(self.x.get() + 1); + } +} + +fn foo(x: &Cell) -> foo { + foo { + x: x + } +} + +pub fn main() { + let x = &Cell::new(0); + { + let l = &[foo(x)]; + assert_eq!(l[0].x.get(), 0); + } + assert_eq!(x.get(), 1); +} diff --git a/src/test/ui/array-slice-vec/vec-slice.rs b/src/test/ui/array-slice-vec/vec-slice.rs new file mode 100644 index 00000000000..1f090ddd9c9 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-slice.rs @@ -0,0 +1,9 @@ +// run-pass + + +pub fn main() { + let v = vec![1,2,3,4,5]; + let v2 = &v[1..3]; + assert_eq!(v2[0], 2); + assert_eq!(v2[1], 3); +} diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs new file mode 100644 index 00000000000..84d246dff82 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs @@ -0,0 +1,36 @@ +// run-pass + +#![feature(slice_patterns)] + +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/src/test/ui/array-slice-vec/vec-to_str.rs b/src/test/ui/array-slice-vec/vec-to_str.rs new file mode 100644 index 00000000000..a11cfc8e9b5 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec-to_str.rs @@ -0,0 +1,12 @@ +// run-pass + + +pub fn main() { + assert_eq!(format!("{:?}", vec![0, 1]), "[0, 1]".to_string()); + + let foo = vec![3, 4]; + let bar: &[isize] = &[4, 5]; + + assert_eq!(format!("{:?}", foo), "[3, 4]"); + assert_eq!(format!("{:?}", bar), "[4, 5]"); +} diff --git a/src/test/ui/array-slice-vec/vec.rs b/src/test/ui/array-slice-vec/vec.rs new file mode 100644 index 00000000000..e76c1ab440e --- /dev/null +++ b/src/test/ui/array-slice-vec/vec.rs @@ -0,0 +1,15 @@ +// run-pass + + + +pub fn main() { + let v: Vec = vec![10, 20]; + assert_eq!(v[0], 10); + assert_eq!(v[1], 20); + let mut x: usize = 0; + assert_eq!(v[x], 10); + assert_eq!(v[x + 1], 20); + x = x + 1; + assert_eq!(v[x], 20); + assert_eq!(v[x - 1], 10); +} diff --git a/src/test/ui/array-slice-vec/vec_cycle.rs b/src/test/ui/array-slice-vec/vec_cycle.rs new file mode 100644 index 00000000000..82bce437282 --- /dev/null +++ b/src/test/ui/array-slice-vec/vec_cycle.rs @@ -0,0 +1,39 @@ +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct C<'a> { + v: Vec>>>, +} + +impl<'a> C<'a> { + fn new() -> C<'a> { + C { v: Vec::new() } + } +} + +fn f() { + let (mut c1, mut c2, mut c3); + c1 = C::new(); + c2 = C::new(); + c3 = C::new(); + + c1.v.push(Cell::new(None)); + c1.v.push(Cell::new(None)); + c2.v.push(Cell::new(None)); + c2.v.push(Cell::new(None)); + c3.v.push(Cell::new(None)); + c3.v.push(Cell::new(None)); + + c1.v[0].set(Some(&c2)); + c1.v[1].set(Some(&c3)); + c2.v[0].set(Some(&c2)); + c2.v[1].set(Some(&c3)); + c3.v[0].set(Some(&c1)); + c3.v[1].set(Some(&c2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/array-slice-vec/vec_cycle_wrapped.rs b/src/test/ui/array-slice-vec/vec_cycle_wrapped.rs new file mode 100644 index 00000000000..1a3606d5e8d --- /dev/null +++ b/src/test/ui/array-slice-vec/vec_cycle_wrapped.rs @@ -0,0 +1,50 @@ +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct Refs<'a> { + v: Vec>>>, +} + +#[derive(Debug)] +struct C<'a> { + refs: Refs<'a>, +} + +impl<'a> Refs<'a> { + fn new() -> Refs<'a> { + Refs { v: Vec::new() } + } +} + +impl<'a> C<'a> { + fn new() -> C<'a> { + C { refs: Refs::new() } + } +} + +fn f() { + let (mut c1, mut c2, mut c3); + c1 = C::new(); + c2 = C::new(); + c3 = C::new(); + + c1.refs.v.push(Cell::new(None)); + c1.refs.v.push(Cell::new(None)); + c2.refs.v.push(Cell::new(None)); + c2.refs.v.push(Cell::new(None)); + c3.refs.v.push(Cell::new(None)); + c3.refs.v.push(Cell::new(None)); + + c1.refs.v[0].set(Some(&c2)); + c1.refs.v[1].set(Some(&c3)); + c2.refs.v[0].set(Some(&c2)); + c2.refs.v[1].set(Some(&c3)); + c3.refs.v[0].set(Some(&c1)); + c3.refs.v[1].set(Some(&c2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/array-slice-vec/vector-no-ann-2.rs b/src/test/ui/array-slice-vec/vector-no-ann-2.rs new file mode 100644 index 00000000000..dd8f402f3f6 --- /dev/null +++ b/src/test/ui/array-slice-vec/vector-no-ann-2.rs @@ -0,0 +1,7 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { let _quux: Box> = box Vec::new(); } diff --git a/src/test/ui/artificial-block.rs b/src/test/ui/artificial-block.rs new file mode 100644 index 00000000000..2e383e1a7c6 --- /dev/null +++ b/src/test/ui/artificial-block.rs @@ -0,0 +1,5 @@ +// run-pass + +fn f() -> isize { { return 3; } } + +pub fn main() { assert_eq!(f(), 3); } diff --git a/src/test/ui/as-precedence.rs b/src/test/ui/as-precedence.rs new file mode 100644 index 00000000000..a9f6fceb08f --- /dev/null +++ b/src/test/ui/as-precedence.rs @@ -0,0 +1,9 @@ +// run-pass + +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/src/test/ui/asm-concat-src.rs b/src/test/ui/asm-concat-src.rs new file mode 100644 index 00000000000..c4160bfeca1 --- /dev/null +++ b/src/test/ui/asm-concat-src.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-emscripten no asm + +#![feature(asm)] + +pub fn main() { + unsafe { asm!(concat!("", "")) }; +} diff --git a/src/test/ui/asm-in-moved.rs b/src/test/ui/asm-in-moved.rs new file mode 100644 index 00000000000..6525d2f53b0 --- /dev/null +++ b/src/test/ui/asm-in-moved.rs @@ -0,0 +1,31 @@ +// run-pass + +#![feature(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 { + 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/src/test/ui/asm-in-out-operand.rs b/src/test/ui/asm-in-out-operand.rs new file mode 100644 index 00000000000..13d0363a6a0 --- /dev/null +++ b/src/test/ui/asm-in-out-operand.rs @@ -0,0 +1,56 @@ +// run-pass + +#![feature(asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +unsafe fn next_power_of_2(n: u32) -> u32 { + let mut tmp = n; + asm!("dec $0" : "+rm"(tmp) :: "cc"); + let mut shift = 1_u32; + while shift <= 16 { + asm!( + "shr %cl, $2 + or $2, $0 + shl $$1, $1" + : "+&rm"(tmp), "+{ecx}"(shift) : "r"(tmp) : "cc" + ); + } + 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. + 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. + 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/src/test/ui/asm-indirect-memory.rs b/src/test/ui/asm-indirect-memory.rs new file mode 100644 index 00000000000..2e8011af502 --- /dev/null +++ b/src/test/ui/asm-indirect-memory.rs @@ -0,0 +1,43 @@ +// run-pass + +#![feature(asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn read(ptr: &u32) -> u32 { + let out: u32; + unsafe { + 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 { + 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 { + 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/src/test/ui/asm-out-assign.rs b/src/test/ui/asm-out-assign.rs new file mode 100644 index 00000000000..ed63d1b4d49 --- /dev/null +++ b/src/test/ui/asm-out-assign.rs @@ -0,0 +1,25 @@ +// run-pass + +#![feature(asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub fn main() { + let x: isize; + unsafe { + // Treat the output as initialization. + 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. + 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/src/test/ui/assert-eq-trailing-comma.rs b/src/test/ui/assert-eq-trailing-comma.rs new file mode 100644 index 00000000000..7071f80d7f7 --- /dev/null +++ b/src/test/ui/assert-eq-trailing-comma.rs @@ -0,0 +1,5 @@ +// run-pass + +fn main() { + assert_eq!(1, 1,); +} diff --git a/src/test/ui/assert-escape.rs b/src/test/ui/assert-escape.rs new file mode 100644 index 00000000000..00e51d42cab --- /dev/null +++ b/src/test/ui/assert-escape.rs @@ -0,0 +1,5 @@ +// run-pass + +fn main() { + assert!(r#"☃\backslash"#.contains("\\")); +} diff --git a/src/test/ui/assert-ne-trailing-comma.rs b/src/test/ui/assert-ne-trailing-comma.rs new file mode 100644 index 00000000000..03308db9a1f --- /dev/null +++ b/src/test/ui/assert-ne-trailing-comma.rs @@ -0,0 +1,5 @@ +// run-pass + +fn main() { + assert_ne!(1, 2,); +} diff --git a/src/test/ui/assign-assign.rs b/src/test/ui/assign-assign.rs new file mode 100644 index 00000000000..bcf506b398b --- /dev/null +++ b/src/test/ui/assign-assign.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/assoc-oddities-3.rs b/src/test/ui/assoc-oddities-3.rs new file mode 100644 index 00000000000..cd025dc8bee --- /dev/null +++ b/src/test/ui/assoc-oddities-3.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/associated-consts/associated-const-const-eval.rs b/src/test/ui/associated-consts/associated-const-const-eval.rs new file mode 100644 index 00000000000..5a34bb97ca5 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-const-eval.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/associated-consts/associated-const-cross-crate-const-eval.rs b/src/test/ui/associated-consts/associated-const-cross-crate-const-eval.rs new file mode 100644 index 00000000000..611639b84be --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-cross-crate-const-eval.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/associated-consts/associated-const-cross-crate-defaults.rs b/src/test/ui/associated-consts/associated-const-cross-crate-defaults.rs new file mode 100644 index 00000000000..92d9cffecdd --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-cross-crate-defaults.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/associated-consts/associated-const-cross-crate.rs b/src/test/ui/associated-consts/associated-const-cross-crate.rs new file mode 100644 index 00000000000..ecdc112e02d --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-cross-crate.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/associated-consts/associated-const-in-global-const.rs b/src/test/ui/associated-consts/associated-const-in-global-const.rs new file mode 100644 index 00000000000..18d7a121558 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-in-global-const.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/associated-consts/associated-const-inherent-impl.rs b/src/test/ui/associated-consts/associated-const-inherent-impl.rs new file mode 100644 index 00000000000..c6d956dffe1 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-inherent-impl.rs @@ -0,0 +1,11 @@ +// run-pass + +struct Foo; + +impl Foo { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, Foo::ID); +} diff --git a/src/test/ui/associated-consts/associated-const-marks-live-code.rs b/src/test/ui/associated-consts/associated-const-marks-live-code.rs new file mode 100644 index 00000000000..68eb4e25d33 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-marks-live-code.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/associated-consts/associated-const-match-patterns.rs b/src/test/ui/associated-consts/associated-const-match-patterns.rs new file mode 100644 index 00000000000..62c1cb983d1 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-match-patterns.rs @@ -0,0 +1,68 @@ +// 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/src/test/ui/associated-consts/associated-const-outer-ty-refs.rs b/src/test/ui/associated-consts/associated-const-outer-ty-refs.rs new file mode 100644 index 00000000000..f32ca0cccfc --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-outer-ty-refs.rs @@ -0,0 +1,10 @@ +// run-pass +trait Lattice { + const BOTTOM: Self; +} + +impl Lattice for Option { + const BOTTOM: Option = None; +} + +fn main(){} diff --git a/src/test/ui/associated-consts/associated-const-overwrite-default.rs b/src/test/ui/associated-consts/associated-const-overwrite-default.rs new file mode 100644 index 00000000000..445135aef2b --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-overwrite-default.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/associated-consts/associated-const-public-impl.rs b/src/test/ui/associated-consts/associated-const-public-impl.rs new file mode 100644 index 00000000000..787bee0ff02 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-public-impl.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/associated-consts/associated-const-range-match-patterns.rs b/src/test/ui/associated-consts/associated-const-range-match-patterns.rs new file mode 100644 index 00000000000..5276869a702 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-range-match-patterns.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/associated-consts/associated-const-resolution-order.rs b/src/test/ui/associated-consts/associated-const-resolution-order.rs new file mode 100644 index 00000000000..d2ccd30a6e2 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-resolution-order.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/associated-consts/associated-const-self-type.rs b/src/test/ui/associated-consts/associated-const-self-type.rs new file mode 100644 index 00000000000..36e1e4ecce7 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-self-type.rs @@ -0,0 +1,13 @@ +// run-pass + +trait MyInt { + const ONE: Self; +} + +impl MyInt for i32 { + const ONE: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ONE); +} diff --git a/src/test/ui/associated-consts/associated-const-type-parameters.rs b/src/test/ui/associated-consts/associated-const-type-parameters.rs new file mode 100644 index 00000000000..47c3313ec28 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-type-parameters.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/associated-consts/associated-const-ufcs-infer-trait.rs b/src/test/ui/associated-consts/associated-const-ufcs-infer-trait.rs new file mode 100644 index 00000000000..ca44c9f45fc --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-ufcs-infer-trait.rs @@ -0,0 +1,13 @@ +// run-pass + +trait Foo { + const ID: i32; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ID); +} diff --git a/src/test/ui/associated-consts/associated-const-use-default.rs b/src/test/ui/associated-consts/associated-const-use-default.rs new file mode 100644 index 00000000000..adf36b1fff2 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-use-default.rs @@ -0,0 +1,11 @@ +// run-pass + +trait Foo { + const ID: i32 = 1; +} + +impl Foo for i32 {} + +fn main() { + assert_eq!(1, ::ID); +} diff --git a/src/test/ui/associated-consts/associated-const-use-impl-of-same-trait.rs b/src/test/ui/associated-consts/associated-const-use-impl-of-same-trait.rs new file mode 100644 index 00000000000..8f01bae4fcf --- /dev/null +++ b/src/test/ui/associated-consts/associated-const-use-impl-of-same-trait.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/associated-consts/associated-const.rs b/src/test/ui/associated-consts/associated-const.rs new file mode 100644 index 00000000000..e4b1c29f371 --- /dev/null +++ b/src/test/ui/associated-consts/associated-const.rs @@ -0,0 +1,13 @@ +// run-pass + +trait Foo { + const ID: i32; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ID); +} diff --git a/src/test/ui/associated-consts/auxiliary/associated-const-cc-lib.rs b/src/test/ui/associated-consts/auxiliary/associated-const-cc-lib.rs new file mode 100644 index 00000000000..4fcefe32cbf --- /dev/null +++ b/src/test/ui/associated-consts/auxiliary/associated-const-cc-lib.rs @@ -0,0 +1,34 @@ +#![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/src/test/ui/associated-consts/auxiliary/empty-struct.rs b/src/test/ui/associated-consts/auxiliary/empty-struct.rs new file mode 100644 index 00000000000..93275e7143e --- /dev/null +++ b/src/test/ui/associated-consts/auxiliary/empty-struct.rs @@ -0,0 +1,9 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty7(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty6(), +} diff --git a/src/test/ui/associated-item-long-paths.rs b/src/test/ui/associated-item-long-paths.rs new file mode 100644 index 00000000000..aad8c487c5a --- /dev/null +++ b/src/test/ui/associated-item-long-paths.rs @@ -0,0 +1,47 @@ +// run-pass + +use std::mem::size_of; + +// The main point of this test is to ensure that we can parse and resolve +// associated items on associated types. + +trait Foo { + type U; +} + +trait Bar { + // Note 1: Chains of associated items in a path won't type-check. + // Note 2: Associated consts can't depend on type parameters or `Self`, + // which are the only types that an associated type can be referenced on for + // now, so we can only test methods. + fn method() -> u32; + fn generic_method() -> usize; +} + +struct MyFoo; +struct MyBar; + +impl Foo for MyFoo { + type U = MyBar; +} + +impl Bar for MyBar { + fn method() -> u32 { + 2u32 + } + fn generic_method() -> usize { + size_of::() + } +} + +fn foo() + where T: Foo, + T::U: Bar, +{ + assert_eq!(2u32, ::U::method()); + assert_eq!(8usize, ::U::generic_method::()); +} + +fn main() { + foo::(); +} diff --git a/src/test/ui/associated-types/associated-types-basic.rs b/src/test/ui/associated-types/associated-types-basic.rs new file mode 100644 index 00000000000..b7f6721ec4f --- /dev/null +++ b/src/test/ui/associated-types/associated-types-basic.rs @@ -0,0 +1,14 @@ +// run-pass +trait Foo { + type T; +} + +impl Foo for i32 { + type T = isize; +} + +fn main() { + let x: ::T = 22; + let y: isize = 44; + assert_eq!(x * 2, y); +} diff --git a/src/test/ui/associated-types/associated-types-binding-in-trait.rs b/src/test/ui/associated-types/associated-types-binding-in-trait.rs new file mode 100644 index 00000000000..2e42b3a2a44 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-binding-in-trait.rs @@ -0,0 +1,36 @@ +// run-pass +// Test a case where the associated type binding (to `bool`, in this +// case) is derived from the trait definition. Issue #21636. + + +use std::vec; + +pub trait BitIter { + type Iter: Iterator; + fn bit_iter(self) -> ::Iter; +} + +impl BitIter for Vec { + type Iter = vec::IntoIter; + fn bit_iter(self) -> ::Iter { + self.into_iter() + } +} + +fn count(arg: T) -> usize + where T: BitIter +{ + let mut sum = 0; + for i in arg.bit_iter() { + if i { + sum += 1; + } + } + sum +} + +fn main() { + let v = vec![true, false, true]; + let c = count(v); + assert_eq!(c, 2); +} diff --git a/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs b/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs new file mode 100644 index 00000000000..c54bc3cd623 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs @@ -0,0 +1,38 @@ +// run-pass +// Test equality constraints on associated types in a where clause. + +// pretty-expanded FIXME #23616 + +pub trait Foo { + type A; + fn boo(&self) -> ::A; +} + +#[derive(PartialEq)] +pub struct Bar; + +impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { 42 } +} + +impl Foo for char { + type A = Bar; + fn boo(&self) -> Bar { Bar } +} + +fn foo_bar>(x: I) -> Bar { + x.boo() +} + +fn foo_uint>(x: I) -> usize { + x.boo() +} + +pub fn main() { + let a = 42; + foo_uint(a); + + let a = 'a'; + foo_bar(a); +} diff --git a/src/test/ui/associated-types/associated-types-bound.rs b/src/test/ui/associated-types/associated-types-bound.rs new file mode 100644 index 00000000000..0e9a229a5e5 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-bound.rs @@ -0,0 +1,43 @@ +// run-pass +// Test equality constrai32s on associated types in a where clause. + + +pub trait ToI32 { + fn to_i32(&self) -> i32; +} + +impl ToI32 for i32 { + fn to_i32(&self) -> i32 { *self } +} + +impl ToI32 for u32 { + fn to_i32(&self) -> i32 { *self as i32 } +} + +pub trait GetToI32 +{ + type R : ToI32; + + fn get(&self) -> ::R; +} + +impl GetToI32 for i32 { + type R = i32; + fn get(&self) -> i32 { *self } +} + +impl GetToI32 for u32 { + type R = u32; + fn get(&self) -> u32 { *self } +} + +fn foo(g: G) -> i32 + where G : GetToI32 +{ + ToI32::to_i32(&g.get()) +} + +pub fn main() { + assert_eq!(foo(22i32), 22); + assert_eq!(foo(22u32), 22); +} diff --git a/src/test/ui/associated-types/associated-types-cc.rs b/src/test/ui/associated-types/associated-types-cc.rs new file mode 100644 index 00000000000..13f1d27203a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-cc.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_variables)] +// aux-build:associated-types-cc-lib.rs + +// Test that we are able to reference cross-crate traits that employ +// associated types. + +extern crate associated_types_cc_lib as bar; + +use bar::Bar; + +fn foo(b: B) -> ::T { + Bar::get(None::) +} + +fn main() { + println!("{}", foo(3)); +} diff --git a/src/test/ui/associated-types/associated-types-conditional-dispatch.rs b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs new file mode 100644 index 00000000000..70ee60517ae --- /dev/null +++ b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs @@ -0,0 +1,66 @@ +// run-pass +// Test that we evaluate projection predicates to winnow out +// candidates during trait selection and method resolution (#20296). +// If we don't properly winnow out candidates based on the output type +// `Target=[A]`, then the impl marked with `(*)` is seen to conflict +// with all the others. + +// pretty-expanded FIXME #23616 + +use std::marker::PhantomData; +use std::ops::Deref; + +pub trait MyEq { + fn eq(&self, u: &U) -> bool; +} + +impl MyEq<[B]> for [A] + where A : MyEq +{ + fn eq(&self, other: &[B]) -> bool { + self.len() == other.len() && + self.iter().zip(other).all(|(a, b)| MyEq::eq(a, b)) + } +} + +// (*) This impl conflicts with everything unless the `Target=[A]` +// constraint is considered. +impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs + where A: MyEq, Lhs: Deref +{ + fn eq(&self, other: &[B; 0]) -> bool { + MyEq::eq(&**self, other) + } +} + +struct DerefWithHelper { + pub helper: H, + pub marker: PhantomData, +} + +trait Helper { + fn helper_borrow(&self) -> &T; +} + +impl Helper for Option { + fn helper_borrow(&self) -> &T { + self.as_ref().unwrap() + } +} + +impl> Deref for DerefWithHelper { + type Target = T; + + fn deref(&self) -> &T { + self.helper.helper_borrow() + } +} + +pub fn check(x: T, y: T) -> bool { + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), + marker: PhantomData }; + d.eq(&y) +} + +pub fn main() { +} diff --git a/src/test/ui/associated-types/associated-types-constant-type.rs b/src/test/ui/associated-types/associated-types-constant-type.rs new file mode 100644 index 00000000000..1e4c113a5fb --- /dev/null +++ b/src/test/ui/associated-types/associated-types-constant-type.rs @@ -0,0 +1,31 @@ +// run-pass + +trait SignedUnsigned { + type Opposite; + fn convert(self) -> Self::Opposite; +} + +impl SignedUnsigned for isize { + type Opposite = usize; + + fn convert(self) -> usize { + self as usize + } +} + +impl SignedUnsigned for usize { + type Opposite = isize; + + fn convert(self) -> isize { + self as isize + } +} + +fn get(x: isize) -> ::Opposite { + x.convert() +} + +fn main() { + let x = get(22); + assert_eq!(22, x); +} diff --git a/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs b/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs new file mode 100644 index 00000000000..96ba2ee3b62 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs new file mode 100644 index 00000000000..12ca100435a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// Check that we do not report ambiguities when equivalent predicates +// (modulo bound lifetime names) appears in the environment +// twice. Issue #21965. + +// pretty-expanded FIXME #23616 + +fn foo(t: T) -> i32 + where T : for<'a> Fn(&'a u8) -> i32, + T : for<'b> Fn(&'b u8) -> i32, +{ + t(&3) +} + +fn main() { +} diff --git a/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs new file mode 100644 index 00000000000..9ffccd3d8ff --- /dev/null +++ b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// Check that we do not report ambiguities when the same predicate +// appears in the environment twice. Issue #21965. + +// pretty-expanded FIXME #23616 + +trait Foo { + type B; + + fn get() -> Self::B; +} + +fn foo() -> () + where T : Foo, T : Foo +{ + ::get() +} + +fn main() { +} diff --git a/src/test/ui/associated-types/associated-types-enum-field-named.rs b/src/test/ui/associated-types/associated-types-enum-field-named.rs new file mode 100644 index 00000000000..896d67213e9 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-enum-field-named.rs @@ -0,0 +1,35 @@ +// run-pass +// Test associated types appearing in struct-like enum variants. + + +use self::VarValue::*; + +pub trait UnifyKey { + type Value; + fn to_index(&self) -> usize; +} + +pub enum VarValue { + Redirect { to: K }, + Root { value: K::Value, rank: usize }, +} + +fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { + match table[key.to_index()] { + VarValue::Redirect { to: ref k } => get(table, k), + VarValue::Root { value: ref v, rank: _ } => v, + } +} + +impl UnifyKey for usize { + type Value = Option; + fn to_index(&self) -> usize { *self } +} + +fn main() { + let table = vec![/* 0 */ Redirect { to: 1 }, + /* 1 */ Redirect { to: 3 }, + /* 2 */ Root { value: Some('x'), rank: 0 }, + /* 3 */ Redirect { to: 2 }]; + assert_eq!(get(&table, &0), &Some('x')); +} diff --git a/src/test/ui/associated-types/associated-types-enum-field-numbered.rs b/src/test/ui/associated-types/associated-types-enum-field-numbered.rs new file mode 100644 index 00000000000..77ced3c0781 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-enum-field-numbered.rs @@ -0,0 +1,35 @@ +// run-pass +// Test associated types appearing in tuple-like enum variants. + + +use self::VarValue::*; + +pub trait UnifyKey { + type Value; + fn to_index(&self) -> usize; +} + +pub enum VarValue { + Redirect(K), + Root(K::Value, usize), +} + +fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { + match table[key.to_index()] { + VarValue::Redirect(ref k) => get(table, k), + VarValue::Root(ref v, _) => v, + } +} + +impl UnifyKey for usize { + type Value = Option; + fn to_index(&self) -> usize { *self } +} + +fn main() { + let table = vec![/* 0 */ Redirect(1), + /* 1 */ Redirect(3), + /* 2 */ Root(Some('x'), 0), + /* 3 */ Redirect(2)]; + assert_eq!(get(&table, &0), &Some('x')); +} diff --git a/src/test/ui/associated-types/associated-types-eq-obj.rs b/src/test/ui/associated-types/associated-types-eq-obj.rs new file mode 100644 index 00000000000..c202c376c5f --- /dev/null +++ b/src/test/ui/associated-types/associated-types-eq-obj.rs @@ -0,0 +1,25 @@ +// run-pass +// Test equality constraints on associated types inside of an object type + +// pretty-expanded FIXME #23616 + +pub trait Foo { + type A; + fn boo(&self) -> ::A; +} + +pub struct Bar; + +impl Foo for char { + type A = Bar; + fn boo(&self) -> Bar { Bar } +} + +fn baz(x: &dyn Foo) -> Bar { + x.boo() +} + +pub fn main() { + let a = 'a'; + baz(&a); +} diff --git a/src/test/ui/associated-types/associated-types-from-supertrait.rs b/src/test/ui/associated-types/associated-types-from-supertrait.rs new file mode 100644 index 00000000000..8f40b94c099 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-from-supertrait.rs @@ -0,0 +1,8 @@ +// run-pass + +trait Foo: Iterator {} +trait Bar: Foo {} + +fn main() { + let _: &dyn Bar; +} diff --git a/src/test/ui/associated-types/associated-types-impl-redirect.rs b/src/test/ui/associated-types/associated-types-impl-redirect.rs new file mode 100644 index 00000000000..8fa20cdf4b7 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-impl-redirect.rs @@ -0,0 +1,51 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_imports)] +// Test how resolving a projection interacts with inference. In this +// case, we were eagerly unifying the type variable for the iterator +// type with `I` from the where clause, ignoring the in-scope `impl` +// for `ByRef`. The right answer was to consider the result ambiguous +// until more type information was available. + +#![feature(lang_items)] +#![no_implicit_prelude] + +use std::marker::Sized; +use std::option::Option::{None, Some, self}; + +trait Iterator { + type Item; + + fn next(&mut self) -> Option; +} + +trait IteratorExt: Iterator + Sized { + fn by_ref(&mut self) -> ByRef { + ByRef(self) + } +} + +impl IteratorExt for I where I: Iterator {} + +struct ByRef<'a, I: 'a + Iterator>(&'a mut I); + +impl<'a, I: Iterator> Iterator for ByRef<'a, I> { + type Item = I::Item; + + fn next(&mut self) -> Option< ::Item > { + self.0.next() + } +} + +fn is_iterator_of>(_: &I) {} + +fn test>(mut it: I) { + is_iterator_of::(&it.by_ref()); +} + +fn test2, I2: Iterator>(mut it: I2) { + is_iterator_of::(&it) +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs b/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs new file mode 100644 index 00000000000..88bb5fe0afe --- /dev/null +++ b/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs @@ -0,0 +1,17 @@ +// run-pass +// Test the case where we resolve `C::Result` and the trait bound +// itself includes a `Self::Item` shorthand. +// +// Regression test for issue #33425. + +trait ParallelIterator { + type Item; + fn drive_unindexed(self, consumer: C) -> C::Result + where C: Consumer; +} + +pub trait Consumer { + type Result; +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-in-default-method.rs b/src/test/ui/associated-types/associated-types-in-default-method.rs new file mode 100644 index 00000000000..80ffbf585fb --- /dev/null +++ b/src/test/ui/associated-types/associated-types-in-default-method.rs @@ -0,0 +1,27 @@ +// run-pass + +trait Get { + type Value; + fn get(&self) -> &::Value; + fn grab(&self) -> &::Value { + self.get() + } +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +fn main() { + let s = Struct { + x: 100, + }; + assert_eq!(*s.grab(), 100); +} diff --git a/src/test/ui/associated-types/associated-types-in-fn.rs b/src/test/ui/associated-types/associated-types-in-fn.rs new file mode 100644 index 00000000000..9c588a528fe --- /dev/null +++ b/src/test/ui/associated-types/associated-types-in-fn.rs @@ -0,0 +1,28 @@ +// run-pass + +trait Get { + type Value; + fn get(&self) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +fn grab(x: &T) -> &::Value { + x.get() +} + +fn main() { + let s = Struct { + x: 100, + }; + assert_eq!(*grab(&s), 100); +} diff --git a/src/test/ui/associated-types/associated-types-in-impl-generics.rs b/src/test/ui/associated-types/associated-types-in-impl-generics.rs new file mode 100644 index 00000000000..0ddd99cbfa8 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-in-impl-generics.rs @@ -0,0 +1,36 @@ +// run-pass + +trait Get { + type Value; + fn get(&self) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +trait Grab { + type U; + fn grab(&self) -> &::U; +} + +impl Grab for T { + type U = ::Value; + fn grab(&self) -> &::Value { + self.get() + } +} + +fn main() { + let s = Struct { + x: 100, + }; + assert_eq!(*s.grab(), 100); +} diff --git a/src/test/ui/associated-types/associated-types-in-inherent-method.rs b/src/test/ui/associated-types/associated-types-in-inherent-method.rs new file mode 100644 index 00000000000..1f29e966851 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-in-inherent-method.rs @@ -0,0 +1,30 @@ +// run-pass + +trait Get { + type Value; + fn get(&self) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +impl Struct { + fn grab(x: &T) -> &::Value { + x.get() + } +} + +fn main() { + let s = Struct { + x: 100, + }; + assert_eq!(*Struct::grab(&s), 100); +} diff --git a/src/test/ui/associated-types/associated-types-issue-20220.rs b/src/test/ui/associated-types/associated-types-issue-20220.rs new file mode 100644 index 00000000000..19fa7a6085a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-issue-20220.rs @@ -0,0 +1,28 @@ +// run-pass +// Test references to `Self::Item` in the trait. Issue #20220. + + +use std::vec; + +trait IntoIteratorX { + type Item; + type IntoIter: Iterator; + + fn into_iter_x(self) -> Self::IntoIter; +} + +impl IntoIteratorX for Vec { + type Item = T; + type IntoIter = vec::IntoIter; + + fn into_iter_x(self) -> vec::IntoIter { + self.into_iter() + } +} + +fn main() { + let vec = vec![1, 2, 3]; + for (i, e) in vec.into_iter().enumerate() { + assert_eq!(i+1, e); + } +} diff --git a/src/test/ui/associated-types/associated-types-issue-20371.rs b/src/test/ui/associated-types/associated-types-issue-20371.rs new file mode 100644 index 00000000000..ae8a8767d27 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-issue-20371.rs @@ -0,0 +1,9 @@ +// run-pass +// Test that we are able to have an impl that defines an associated type +// before the actual trait. + +// pretty-expanded FIXME #23616 + +impl X for f64 { type Y = isize; } +trait X { type Y; } +fn main() {} diff --git a/src/test/ui/associated-types/associated-types-issue-21212.rs b/src/test/ui/associated-types/associated-types-issue-21212.rs new file mode 100644 index 00000000000..ce27eac4d0e --- /dev/null +++ b/src/test/ui/associated-types/associated-types-issue-21212.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_variables)] +// Regression test for #21212: an overflow occurred during trait +// checking where normalizing `Self::Input` led to normalizing the +// where clauses in the environment which in turn required normalizing +// `Self::Input`. + + +pub trait Parser { + type Input; + + fn parse(input: ::Input) { + panic!() + } +} + +impl

Parser for P { + type Input = (); +} + +fn main() { +} diff --git a/src/test/ui/associated-types/associated-types-iterator-binding.rs b/src/test/ui/associated-types/associated-types-iterator-binding.rs new file mode 100644 index 00000000000..7c5528c986e --- /dev/null +++ b/src/test/ui/associated-types/associated-types-iterator-binding.rs @@ -0,0 +1,19 @@ +// run-pass + +fn pairwise_sub>(mut t: T) -> isize { + let mut result = 0; + loop { + let front = t.next(); + let back = t.next_back(); + match (front, back) { + (Some(f), Some(b)) => { result += b - f; } + _ => { return result; } + } + } +} + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6]; + let r = pairwise_sub(v.into_iter()); + assert_eq!(r, 9); +} diff --git a/src/test/ui/associated-types/associated-types-method.rs b/src/test/ui/associated-types/associated-types-method.rs new file mode 100644 index 00000000000..64132cfeed7 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-method.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/associated-types/associated-types-nested-projections.rs b/src/test/ui/associated-types/associated-types-nested-projections.rs new file mode 100644 index 00000000000..76ba7496250 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-nested-projections.rs @@ -0,0 +1,44 @@ +// run-pass +#![allow(unused_variables)] +// Test that we can resolve nested projection types. Issue #20666. + +// pretty-expanded FIXME #23616 + +use std::slice; + +trait Bound {} + +impl<'a> Bound for &'a i32 {} + +trait IntoIterator { + type Iter: Iterator; + + fn into_iter(self) -> Self::Iter; +} + +impl<'a, T> IntoIterator for &'a [T; 3] { + type Iter = slice::Iter<'a, T>; + + fn into_iter(self) -> slice::Iter<'a, T> { + self.iter() + } +} + +fn foo(x: X) where + X: IntoIterator, + <::Iter as Iterator>::Item: Bound, +{ +} + +fn bar(x: X) where + T: Bound, + I: Iterator, + X: IntoIterator, +{ + +} + +fn main() { + foo(&[0, 1, 2]); + bar(&[0, 1, 2]); +} diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs new file mode 100644 index 00000000000..7c54efb83c2 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(unused_variables)] +// Test that we normalize associated types that appear in a bound that +// contains a binding. Issue #21664. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +pub trait Integral { + type Opposite; +} + +impl Integral for i32 { + type Opposite = u32; +} + +impl Integral for u32 { + type Opposite = i32; +} + +pub trait FnLike { + type R; + + fn dummy(&self, a: A) -> Self::R { loop { } } +} + +fn foo() + where T : FnLike<::Opposite, R=bool> +{ + bar::(); +} + +fn bar() + where T : FnLike +{} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs new file mode 100644 index 00000000000..e09aa3663c6 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_variables)] +// Test that we normalize associated types that appear in bounds; if +// we didn't, the call to `self.split2()` fails to type check. + +// pretty-expanded FIXME #23616 + +use std::marker::PhantomData; + +struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>); +struct SplitsN(PhantomData); + +trait SliceExt2 { + type Item; + + fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN> + where P: FnMut(&Self::Item) -> bool; +} + +impl SliceExt2 for [T] { + type Item = T; + + fn split2

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

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + SliceExt2::split2(self, pred); + loop {} + } +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs new file mode 100644 index 00000000000..dcfae0f37e1 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_variables)] +// Test that we normalize associated types that appear in bounds; if +// we didn't, the call to `self.split2()` fails to type check. + +// pretty-expanded FIXME #23616 + +use std::marker::PhantomData; + +struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>); +struct SplitsN(PhantomData); + +trait SliceExt2 { + type Item; + + fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN> + where P: FnMut(&Self::Item) -> bool; +} + +impl SliceExt2 for [T] { + type Item = T; + + fn split2

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

(&self, n: usize, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + self.split2(pred); + loop {} + } +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs b/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs new file mode 100644 index 00000000000..a04525dcd46 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs @@ -0,0 +1,24 @@ +// run-pass +// Regression test for issue #21010: Normalize associated types in +// various special paths in the `type_is_immediate` function. + +pub trait OffsetState: Sized {} +pub trait Offset { + type State: OffsetState; + fn dummy(&self) { } +} + +#[derive(Copy, Clone)] pub struct X; +impl Offset for X { type State = Y; } + +#[derive(Copy, Clone)] pub struct Y; +impl OffsetState for Y {} + +pub fn now() -> DateTime { from_utc(Y) } + +pub struct DateTime { pub offset: Off::State } +pub fn from_utc(offset: Off::State) -> DateTime { DateTime { offset: offset } } + +pub fn main() { + let _x = now(); +} diff --git a/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs b/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs new file mode 100644 index 00000000000..fc1dba97dfd --- /dev/null +++ b/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs @@ -0,0 +1,98 @@ +// run-pass +// Various uses of `T::Item` syntax where the bound that supplies +// `Item` originates in a where-clause, not the declaration of +// `T`. Issue #20300. + +use std::marker::{PhantomData}; +use std::sync::atomic::{AtomicUsize}; +use std::sync::atomic::Ordering::SeqCst; + +static COUNTER: AtomicUsize = AtomicUsize::new(0); + +// Preamble. +trait Trait { type Item; } +struct Struct; +impl Trait for Struct { + type Item = u32; +} + +// Where-clause attached on the method which declares `T`. +struct A; +impl A { + fn foo(_x: T::Item) where T: Trait { + COUNTER.fetch_add(1, SeqCst); + } +} + +// Where-clause attached on the method to a parameter from the struct. +struct B(PhantomData); +impl B { + fn foo(_x: T::Item) where T: Trait { + COUNTER.fetch_add(10, SeqCst); + } +} + +// Where-clause attached to free fn. +fn c(_: T::Item) where T : Trait { + COUNTER.fetch_add(100, SeqCst); +} + +// Where-clause attached to defaulted and non-defaulted trait method. +trait AnotherTrait { + fn method(&self, _: T::Item) where T: Trait; + fn default_method(&self, _: T::Item) where T: Trait { + COUNTER.fetch_add(1000, SeqCst); + } +} +struct D; +impl AnotherTrait for D { + fn method(&self, _: T::Item) where T: Trait { + COUNTER.fetch_add(10000, SeqCst); + } +} + +// Where-clause attached to trait and impl containing the method. +trait YetAnotherTrait + where T : Trait +{ + fn method(&self, _: T::Item); + fn default_method(&self, _: T::Item) { + COUNTER.fetch_add(100000, SeqCst); + } +} +struct E(PhantomData); +impl YetAnotherTrait for E + where T : Trait +{ + fn method(&self, _: T::Item) { + COUNTER.fetch_add(1000000, SeqCst); + } +} + +// Where-clause attached to inherent impl containing the method. +struct F(PhantomData); +impl F where T : Trait { + fn method(&self, _: T::Item) { + COUNTER.fetch_add(10000000, SeqCst); + } +} + +// Where-clause attached to struct. +#[allow(dead_code)] +struct G where T : Trait { + data: T::Item, + phantom: PhantomData, +} + +fn main() { + A::foo::(22); + B::::foo(22); + c::(22); + D.method::(22); + D.default_method::(22); + E(PhantomData::).method(22); + E(PhantomData::).default_method(22); + F(PhantomData::).method(22); + G:: { data: 22, phantom: PhantomData }; + assert_eq!(COUNTER.load(SeqCst), 11111111); +} diff --git a/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs b/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs new file mode 100644 index 00000000000..107e6b4ce0c --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_variables)] +// Test that we correctly handle projection bounds appearing in the +// supertrait list (and in conjunction with overloaded operators). In +// this case, the `Result=Self` binding in the supertrait listing of +// `Int` was being ignored. + +trait Not { + type Result; + + fn not(self) -> Self::Result; +} + +trait Int: Not + Sized { + fn count_ones(self) -> usize; + fn count_zeros(self) -> usize { + // neither works + let x: Self = self.not(); + 0 + } +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs b/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs new file mode 100644 index 00000000000..a59c327be21 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs @@ -0,0 +1,38 @@ +// run-pass +// Test where the impl self type uses a projection from a constant type. + + +trait Int +{ + type T; + + fn dummy(&self) { } +} + +trait NonZero +{ + fn non_zero(self) -> bool; +} + +impl Int for i32 { type T = i32; } +impl Int for i64 { type T = i64; } +impl Int for u32 { type T = u32; } +impl Int for u64 { type T = u64; } + +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } + +fn main () +{ + assert!(NonZero::non_zero(22_i32)); + assert!(NonZero::non_zero(22_i64)); + assert!(NonZero::non_zero(22_u32)); + assert!(NonZero::non_zero(22_u64)); + + assert!(!NonZero::non_zero(0_i32)); + assert!(!NonZero::non_zero(0_i64)); + assert!(!NonZero::non_zero(0_u32)); + assert!(!NonZero::non_zero(0_u64)); +} diff --git a/src/test/ui/associated-types/associated-types-projection-in-object-type.rs b/src/test/ui/associated-types/associated-types-projection-in-object-type.rs new file mode 100644 index 00000000000..eec95a141f5 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-in-object-type.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +// Corrected regression test for #20831. The original did not compile. +// When fixed, it revealed another problem concerning projections that +// appear in associated type bindings in object types, which were not +// being properly flagged. + +// pretty-expanded FIXME #23616 + +use std::ops::{Shl, Shr}; +use std::cell::RefCell; + +pub trait Subscriber { + type Input; + + fn dummy(&self) { } +} + +pub trait Publisher<'a> { + type Output; + fn subscribe(&mut self, _: Box + 'a>); +} + +pub trait Processor<'a> : Subscriber + Publisher<'a> { } + +impl<'a, P> Processor<'a> for P where P : Subscriber + Publisher<'a> { } + +struct MyStruct<'a> { + sub: Box + 'a> +} + +impl<'a> Publisher<'a> for MyStruct<'a> { + type Output = u64; + fn subscribe(&mut self, t : Box + 'a>) { + self.sub = t; + } +} + +fn main() {} diff --git a/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs b/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs new file mode 100644 index 00000000000..ead405fcf01 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] +// Test that we are handle to correctly handle a projection type +// that appears in a supertrait bound. Issue #20559. + + +trait A +{ + type TA; + + fn dummy(&self) { } +} + +trait B +{ + fn foo (&self, t : TB) -> String; +} + +trait C : B<::TA> { } + +struct X; + +impl A for X +{ + type TA = i32; +} + +struct Y; + +impl C for Y { } + +// Both of these impls are required for successful compilation +impl B for Y +{ + fn foo (&self, t : i32) -> String + { + format!("First {}", t) + } +} + +fn main () +{ + let y = Y; + assert_eq!(y.foo(5), format!("First 5")); +} diff --git a/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs b/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs new file mode 100644 index 00000000000..e9a26e53c3c --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test a where clause that uses a non-normalized projection type. + +// pretty-expanded FIXME #23616 + +trait Int +{ + type T; + + fn dummy(&self) { } +} + +trait NonZero +{ + fn non_zero(self) -> bool; +} + +fn foo,J>(t: I) -> bool + where ::T : NonZero + // ^~~~~~~~~~~~~ canonical form is just J +{ + bar::() +} + +fn bar() -> bool { true } + +fn main () +{ +} diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs new file mode 100644 index 00000000000..5f06a829600 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs @@ -0,0 +1,35 @@ +// run-pass +// Check that we do not get an error when you use `::Value` in +// the trait definition if there is no default method and for every impl, +// `Self` does implement `Get`. +// +// See also 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/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs new file mode 100644 index 00000000000..3c830d37060 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + type Bar; + fn get_bar() -> >::Bar; +} + +fn main() { } diff --git a/src/test/ui/associated-types/associated-types-ref-from-struct.rs b/src/test/ui/associated-types/associated-types-ref-from-struct.rs new file mode 100644 index 00000000000..3ccba289e4b --- /dev/null +++ b/src/test/ui/associated-types/associated-types-ref-from-struct.rs @@ -0,0 +1,55 @@ +// run-pass +// Test associated type references in structure fields. + +// pretty-expanded FIXME #23616 + +trait Test { + type V; + + fn test(&self, value: &Self::V) -> bool; +} + +/////////////////////////////////////////////////////////////////////////// + +struct TesterPair { + tester: T, + value: T::V, +} + +impl TesterPair { + fn new(tester: T, value: T::V) -> TesterPair { + TesterPair { tester: tester, value: value } + } + + fn test(&self) -> bool { + self.tester.test(&self.value) + } +} + +/////////////////////////////////////////////////////////////////////////// + +struct EqU32(u32); +impl Test for EqU32 { + type V = u32; + + fn test(&self, value: &u32) -> bool { + self.0 == *value + } +} + +struct EqI32(i32); +impl Test for EqI32 { + type V = i32; + + fn test(&self, value: &i32) -> bool { + self.0 == *value + } +} + +fn main() { + let tester = TesterPair::new(EqU32(22), 23); + tester.test(); + + let tester = TesterPair::new(EqI32(22), 23); + tester.test(); +} diff --git a/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs b/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs new file mode 100644 index 00000000000..4a490ed0387 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs @@ -0,0 +1,23 @@ +// run-pass +// Test associated type references in a struct literal. Issue #20535. + + +pub trait Foo { + type Bar; + + fn dummy(&self) { } +} + +impl Foo for isize { + type Bar = isize; +} + +struct Thing { + a: F, + b: F::Bar, +} + +fn main() { + let thing = Thing{a: 1, b: 2}; + assert_eq!(thing.a + 1, thing.b); +} diff --git a/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs b/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs new file mode 100644 index 00000000000..b722506dbbf --- /dev/null +++ b/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// Regression test for #20582. This test caused an ICE related to +// inconsistent region erasure in codegen. + +// pretty-expanded FIXME #23616 + +struct Foo<'a> { + buf: &'a[u8] +} + +impl<'a> Iterator for Foo<'a> { + type Item = &'a[u8]; + + fn next(&mut self) -> Option<::Item> { + Some(self.buf) + } +} + +fn main() { +} diff --git a/src/test/ui/associated-types/associated-types-resolve-lifetime.rs b/src/test/ui/associated-types/associated-types-resolve-lifetime.rs new file mode 100644 index 00000000000..52f2324d72a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-resolve-lifetime.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Get { + fn get(&self) -> T; +} + +trait Trait<'a> { + type T: 'static; + type U: Get<&'a isize>; + + fn dummy(&'a self) { } +} + +fn main() {} diff --git a/src/test/ui/associated-types/associated-types-return.rs b/src/test/ui/associated-types/associated-types-return.rs new file mode 100644 index 00000000000..997a48b0379 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-return.rs @@ -0,0 +1,46 @@ +// run-pass +// Test equality constraints on associated types in a where clause. + + +pub trait Foo { + type A; + fn boo(&self) -> ::A; +} + +#[derive(PartialEq, Debug)] +pub struct Bar; + +impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { 42 } +} + +impl Foo for Bar { + type A = isize; + fn boo(&self) -> isize { 43 } +} + +impl Foo for char { + type A = Bar; + fn boo(&self) -> Bar { Bar } +} + +fn foo1>(x: I) -> Bar { + x.boo() +} + +fn foo2(x: I) -> ::A { + x.boo() +} + +pub fn main() { + let a = 42; + assert_eq!(foo2(a), 42); + + let a = Bar; + assert_eq!(foo2(a), 43); + + let a = 'a'; + foo1(a); + assert_eq!(foo2(a), Bar); +} diff --git a/src/test/ui/associated-types/associated-types-simple.rs b/src/test/ui/associated-types/associated-types-simple.rs new file mode 100644 index 00000000000..2e2dfd80726 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-simple.rs @@ -0,0 +1,24 @@ +// run-pass + +trait Get { + type Value; + fn get(&self) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +fn main() { + let s = Struct { + x: 100, + }; + assert_eq!(*s.get(), 100); +} diff --git a/src/test/ui/associated-types/associated-types-stream.rs b/src/test/ui/associated-types/associated-types-stream.rs new file mode 100644 index 00000000000..96954528aaa --- /dev/null +++ b/src/test/ui/associated-types/associated-types-stream.rs @@ -0,0 +1,39 @@ +// run-pass +// Test references to the trait `Stream` in the bounds for associated +// types defined on `Stream`. Issue #20551. + + +trait Stream { + type Car; + type Cdr: Stream; + + fn car(&self) -> Self::Car; + fn cdr(self) -> Self::Cdr; +} + +impl Stream for () { + type Car = (); + type Cdr = (); + fn car(&self) -> () { () } + fn cdr(self) -> () { self } +} + +impl Stream for (T, U) + where T : Clone, U : Stream +{ + type Car = T; + type Cdr = U; + fn car(&self) -> T { self.0.clone() } + fn cdr(self) -> U { self.1 } +} + +fn main() { + let p = (22, (44, (66, ()))); + assert_eq!(p.car(), 22); + + let p = p.cdr(); + assert_eq!(p.car(), 44); + + let p = p.cdr(); + assert_eq!(p.car(), 66); +} diff --git a/src/test/ui/associated-types/associated-types-struct-field-named.rs b/src/test/ui/associated-types/associated-types-struct-field-named.rs new file mode 100644 index 00000000000..c400bf943e1 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-struct-field-named.rs @@ -0,0 +1,35 @@ +// run-pass +// Test that we correctly normalize the type of a struct field +// which has an associated type. + + +pub trait UnifyKey { + type Value; + + fn dummy(&self) { } +} + +pub struct Node { + pub key: K, + pub value: K::Value, +} + +fn foo>,V : Clone>(node: &Node) -> Option { + node.value.clone() +} + +impl UnifyKey for i32 { + type Value = Option; +} + +impl UnifyKey for u32 { + type Value = Option; +} + +pub fn main() { + let node: Node = Node { key: 1, value: Some(22) }; + assert_eq!(foo(&node), Some(22)); + + let node: Node = Node { key: 1, value: Some(22) }; + assert_eq!(foo(&node), Some(22)); +} diff --git a/src/test/ui/associated-types/associated-types-struct-field-numbered.rs b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs new file mode 100644 index 00000000000..fa59060629d --- /dev/null +++ b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs @@ -0,0 +1,32 @@ +// run-pass +// Test that we correctly normalize the type of a struct field +// which has an associated type. + + +pub trait UnifyKey { + type Value; + + fn dummy(&self) { } +} + +pub struct Node(K, K::Value); + +fn foo>,V : Clone>(node: &Node) -> Option { + node.1.clone() +} + +impl UnifyKey for i32 { + type Value = Option; +} + +impl UnifyKey for u32 { + type Value = Option; +} + +pub fn main() { + let node: Node = Node(1, Some(22)); + assert_eq!(foo(&node), Some(22)); + + let node: Node = Node(1, Some(22)); + assert_eq!(foo(&node), Some(22)); +} diff --git a/src/test/ui/associated-types/associated-types-sugar-path.rs b/src/test/ui/associated-types/associated-types-sugar-path.rs new file mode 100644 index 00000000000..66f7672aa43 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-sugar-path.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +// Test paths to associated types using the type-parameter-only sugar. + +use std::ops::Deref; + +pub trait Foo { + type A; + fn boo(&self) -> Self::A; +} + +impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { + 5 + } +} + +// Using a type via a function. +pub fn bar(a: T, x: T::A) -> T::A { + let _: T::A = a.boo(); + x +} + +// Using a type via an impl. +trait C { + fn f(); + fn g(&self) { } +} +struct B(X); +impl C for B { + fn f() { + let x: T::A = panic!(); + } +} + +pub fn main() { + let z: usize = bar(2, 4); +} diff --git a/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs new file mode 100644 index 00000000000..f2a4c6e42a9 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +// Test how resolving a projection interacts with inference. In this +// case, we were eagerly unifying the type variable for the iterator +// type with `I` from the where clause, ignoring the in-scope `impl` +// for `ByRef`. The right answer was to consider the result ambiguous +// until more type information was available. + +#![feature(lang_items)] +#![no_implicit_prelude] + +use std::marker::Sized; +use std::option::Option::{None, Some, self}; + +trait Iterator { + type Item; + + fn next(&mut self) -> Option; +} + +trait IteratorExt: Iterator + Sized { + fn by_ref(&mut self) -> ByRef { + ByRef(self) + } +} + +impl IteratorExt for I where I: Iterator {} + +struct ByRef<'a, I: 'a + Iterator>(&'a mut I); + +impl<'a, A, I> Iterator for ByRef<'a, I> where I: Iterator { + type Item = A; + + fn next(&mut self) -> Option< ::Item > { + self.0.next() + } +} + +fn is_iterator_of>(_: &I) {} + +fn test>(mut it: I) { + is_iterator_of::(&it.by_ref()); +} + +fn main() { } diff --git a/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs b/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs new file mode 100644 index 00000000000..b6785358706 --- /dev/null +++ b/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs @@ -0,0 +1,16 @@ +// Helper for test issue-18048, which tests associated types in a +// cross-crate scenario. + +#![crate_type="lib"] + +pub trait Bar: Sized { + type T; + + fn get(x: Option) -> ::T; +} + +impl Bar for isize { + type T = usize; + + fn get(_: Option) -> usize { 22 } +} diff --git a/src/test/ui/atomic-access-bool.rs b/src/test/ui/atomic-access-bool.rs new file mode 100644 index 00000000000..e9d48bb3b43 --- /dev/null +++ b/src/test/ui/atomic-access-bool.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/atomic-alignment.rs b/src/test/ui/atomic-alignment.rs new file mode 100644 index 00000000000..5bda90d2eab --- /dev/null +++ b/src/test/ui/atomic-alignment.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/atomic-compare_exchange.rs b/src/test/ui/atomic-compare_exchange.rs new file mode 100644 index 00000000000..9b327eef3c8 --- /dev/null +++ b/src/test/ui/atomic-compare_exchange.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/atomic-print.rs b/src/test/ui/atomic-print.rs new file mode 100644 index 00000000000..ef3453da689 --- /dev/null +++ b/src/test/ui/atomic-print.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/attr-main-2.rs b/src/test/ui/attr-main-2.rs new file mode 100644 index 00000000000..3a51f83ba3b --- /dev/null +++ b/src/test/ui/attr-main-2.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(main)] + +pub fn main() { + panic!() +} + +#[main] +fn foo() { +} diff --git a/src/test/ui/attr-main.rs b/src/test/ui/attr-main.rs new file mode 100644 index 00000000000..9c4caaa4a42 --- /dev/null +++ b/src/test/ui/attr-main.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(main)] + +#[main] +fn foo() { +} diff --git a/src/test/ui/attr-shebang.rs b/src/test/ui/attr-shebang.rs new file mode 100644 index 00000000000..cce31c9bb7b --- /dev/null +++ b/src/test/ui/attr-shebang.rs @@ -0,0 +1,6 @@ +// run-pass + +#![allow(stable_features)] +#![feature(rust1)] +pub fn main() { } +// ignore-license diff --git a/src/test/ui/attr-start.rs b/src/test/ui/attr-start.rs new file mode 100644 index 00000000000..6777631484b --- /dev/null +++ b/src/test/ui/attr-start.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(start)] + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + return 0; +} diff --git a/src/test/ui/attr.rs b/src/test/ui/attr.rs new file mode 100644 index 00000000000..9c4caaa4a42 --- /dev/null +++ b/src/test/ui/attr.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(main)] + +#[main] +fn foo() { +} diff --git a/src/test/ui/augmented-assignments-feature-gate-cross.rs b/src/test/ui/augmented-assignments-feature-gate-cross.rs new file mode 100644 index 00000000000..84988feb6f5 --- /dev/null +++ b/src/test/ui/augmented-assignments-feature-gate-cross.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/augmented-assignments-feature-gate.rs b/src/test/ui/augmented-assignments-feature-gate.rs new file mode 100644 index 00000000000..8e686796fee --- /dev/null +++ b/src/test/ui/augmented-assignments-feature-gate.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/auto-instantiate.rs b/src/test/ui/auto-instantiate.rs new file mode 100644 index 00000000000..a58b178287f --- /dev/null +++ b/src/test/ui/auto-instantiate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/auto-is-contextual.rs b/src/test/ui/auto-is-contextual.rs new file mode 100644 index 00000000000..a2ddd5374c0 --- /dev/null +++ b/src/test/ui/auto-is-contextual.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/autobind.rs b/src/test/ui/autobind.rs new file mode 100644 index 00000000000..70606a2a200 --- /dev/null +++ b/src/test/ui/autobind.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs b/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs new file mode 100644 index 00000000000..2482e1878f5 --- /dev/null +++ b/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs b/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs new file mode 100644 index 00000000000..e5f79d78051 --- /dev/null +++ b/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/autoref-autoderef/auto-ref.rs b/src/test/ui/autoref-autoderef/auto-ref.rs new file mode 100644 index 00000000000..b77f9c34213 --- /dev/null +++ b/src/test/ui/autoref-autoderef/auto-ref.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs new file mode 100644 index 00000000000..874f4228277 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs b/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs new file mode 100644 index 00000000000..fadb0784e75 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-method-priority.rs b/src/test/ui/autoref-autoderef/autoderef-method-priority.rs new file mode 100644 index 00000000000..a218f85eba2 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-method-priority.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs new file mode 100644 index 00000000000..9fda3b2c099 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-method-twice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice.rs new file mode 100644 index 00000000000..f53dc8d1032 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-method-twice.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-method.rs b/src/test/ui/autoref-autoderef/autoderef-method.rs new file mode 100644 index 00000000000..262050fa47b --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-method.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/autoref-autoderef/autoderef-privacy.rs b/src/test/ui/autoref-autoderef/autoderef-privacy.rs new file mode 100644 index 00000000000..841be930b77 --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoderef-privacy.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs b/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs new file mode 100644 index 00000000000..70ef7ce87ed --- /dev/null +++ b/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 00000000000..948b5e688eb --- /dev/null +++ b/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![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/src/test/ui/auxiliary/augmented_assignments.rs b/src/test/ui/auxiliary/augmented_assignments.rs new file mode 100644 index 00000000000..d0d3f57459a --- /dev/null +++ b/src/test/ui/auxiliary/augmented_assignments.rs @@ -0,0 +1,8 @@ +use std::ops::AddAssign; + +pub struct Int(pub i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: i32) { + } +} diff --git a/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs new file mode 100644 index 00000000000..cf769f31bf7 --- /dev/null +++ b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub const X: () = (); diff --git a/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs new file mode 100644 index 00000000000..81c16ede909 --- /dev/null +++ b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub const Y: () = (); diff --git a/src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs new file mode 100644 index 00000000000..5330b7a92a3 --- /dev/null +++ b/src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/auxiliary/cond_plugin.rs b/src/test/ui/auxiliary/cond_plugin.rs new file mode 100644 index 00000000000..1f97b556a07 --- /dev/null +++ b/src/test/ui/auxiliary/cond_plugin.rs @@ -0,0 +1,38 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_hygiene)] + +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/src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs new file mode 100644 index 00000000000..d08504005a5 --- /dev/null +++ b/src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs @@ -0,0 +1,31 @@ +#![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/src/test/ui/auxiliary/debuginfo-lto-aux.rs b/src/test/ui/auxiliary/debuginfo-lto-aux.rs new file mode 100644 index 00000000000..dd471154b4f --- /dev/null +++ b/src/test/ui/auxiliary/debuginfo-lto-aux.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/auxiliary/edition-kw-macro-2015.rs b/src/test/ui/auxiliary/edition-kw-macro-2015.rs new file mode 100644 index 00000000000..553ba69303a --- /dev/null +++ b/src/test/ui/auxiliary/edition-kw-macro-2015.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/auxiliary/edition-kw-macro-2018.rs b/src/test/ui/auxiliary/edition-kw-macro-2018.rs new file mode 100644 index 00000000000..f1f4ee28093 --- /dev/null +++ b/src/test/ui/auxiliary/edition-kw-macro-2018.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/auxiliary/foreign_lib.rs b/src/test/ui/auxiliary/foreign_lib.rs new file mode 100644 index 00000000000..de6b0e2118a --- /dev/null +++ b/src/test/ui/auxiliary/foreign_lib.rs @@ -0,0 +1,38 @@ +#![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/src/test/ui/auxiliary/hello_macro.rs b/src/test/ui/auxiliary/hello_macro.rs new file mode 100644 index 00000000000..f2e9e0eaa8c --- /dev/null +++ b/src/test/ui/auxiliary/hello_macro.rs @@ -0,0 +1,21 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_hygiene, 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/src/test/ui/auxiliary/impl_privacy_xc_1.rs b/src/test/ui/auxiliary/impl_privacy_xc_1.rs new file mode 100644 index 00000000000..367b8ec8b88 --- /dev/null +++ b/src/test/ui/auxiliary/impl_privacy_xc_1.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] + +pub struct Fish { + pub x: isize +} + +impl Fish { + pub fn swim(&self) {} +} diff --git a/src/test/ui/auxiliary/impl_privacy_xc_2.rs b/src/test/ui/auxiliary/impl_privacy_xc_2.rs new file mode 100644 index 00000000000..5f9c2268167 --- /dev/null +++ b/src/test/ui/auxiliary/impl_privacy_xc_2.rs @@ -0,0 +1,13 @@ +#![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/src/test/ui/auxiliary/inline_dtor.rs b/src/test/ui/auxiliary/inline_dtor.rs new file mode 100644 index 00000000000..5eee89fdc57 --- /dev/null +++ b/src/test/ui/auxiliary/inline_dtor.rs @@ -0,0 +1,8 @@ +#![crate_name="inline_dtor"] + +pub struct Foo; + +impl Drop for Foo { + #[inline] + fn drop(&mut self) {} +} diff --git a/src/test/ui/auxiliary/inner_static.rs b/src/test/ui/auxiliary/inner_static.rs new file mode 100644 index 00000000000..42dcd379d41 --- /dev/null +++ b/src/test/ui/auxiliary/inner_static.rs @@ -0,0 +1,51 @@ +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/src/test/ui/auxiliary/kinds_in_metadata.rs b/src/test/ui/auxiliary/kinds_in_metadata.rs new file mode 100644 index 00000000000..2a2106ff70a --- /dev/null +++ b/src/test/ui/auxiliary/kinds_in_metadata.rs @@ -0,0 +1,8 @@ +/* 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/src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs b/src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs new file mode 100644 index 00000000000..fa4f33bcef6 --- /dev/null +++ b/src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs @@ -0,0 +1,4 @@ +#![feature(link_cfg)] + +#[link(name = "foo", cfg(foo))] +extern {} diff --git a/src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs b/src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs new file mode 100644 index 00000000000..b365ed91732 --- /dev/null +++ b/src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![feature(link_cfg)] +#![crate_type = "rlib"] + +#[link(name = "foo", cfg(foo))] +extern {} diff --git a/src/test/ui/auxiliary/linkage1.rs b/src/test/ui/auxiliary/linkage1.rs new file mode 100644 index 00000000000..e87ce5e4d31 --- /dev/null +++ b/src/test/ui/auxiliary/linkage1.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub static foo: isize = 3; + +pub fn bar() {} diff --git a/src/test/ui/auxiliary/llvm_pr32379.rs b/src/test/ui/auxiliary/llvm_pr32379.rs new file mode 100644 index 00000000000..8e429767095 --- /dev/null +++ b/src/test/ui/auxiliary/llvm_pr32379.rs @@ -0,0 +1,5 @@ +pub fn pr32379(mut data: u64, f1: bool, f2: bool) -> u64 { + if f1 { data &= !2; } + if f2 { data |= 2; } + data +} diff --git a/src/test/ui/auxiliary/msvc-data-only-lib.rs b/src/test/ui/auxiliary/msvc-data-only-lib.rs new file mode 100644 index 00000000000..ccaa6d8edcf --- /dev/null +++ b/src/test/ui/auxiliary/msvc-data-only-lib.rs @@ -0,0 +1,5 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub static FOO: i32 = 42; diff --git a/src/test/ui/auxiliary/nested_item.rs b/src/test/ui/auxiliary/nested_item.rs new file mode 100644 index 00000000000..9db9d19d6f6 --- /dev/null +++ b/src/test/ui/auxiliary/nested_item.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/auxiliary/proc_macro_def.rs b/src/test/ui/auxiliary/proc_macro_def.rs new file mode 100644 index 00000000000..dfc5a42d19c --- /dev/null +++ b/src/test/ui/auxiliary/proc_macro_def.rs @@ -0,0 +1,35 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_hygiene)] + +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/src/test/ui/auxiliary/reachable-unnameable-items.rs b/src/test/ui/auxiliary/reachable-unnameable-items.rs new file mode 100644 index 00000000000..20f110b1a8c --- /dev/null +++ b/src/test/ui/auxiliary/reachable-unnameable-items.rs @@ -0,0 +1,106 @@ +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/src/test/ui/auxiliary/reexport-should-still-link.rs b/src/test/ui/auxiliary/reexport-should-still-link.rs new file mode 100644 index 00000000000..237ea8dfcf3 --- /dev/null +++ b/src/test/ui/auxiliary/reexport-should-still-link.rs @@ -0,0 +1,5 @@ +pub use foo::bar; + +mod foo { + pub fn bar() {} +} diff --git a/src/test/ui/auxiliary/rmeta-rmeta.rs b/src/test/ui/auxiliary/rmeta-rmeta.rs new file mode 100644 index 00000000000..4a6d055a81f --- /dev/null +++ b/src/test/ui/auxiliary/rmeta-rmeta.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic +// compile-flags: --emit=metadata + +#![crate_type="rlib"] +#![crate_name="rmeta_aux"] + +pub struct Foo { + pub field2: i32, +} diff --git a/src/test/ui/auxiliary/svh-a-base.rs b/src/test/ui/auxiliary/svh-a-base.rs new file mode 100644 index 00000000000..36b41fc818f --- /dev/null +++ b/src/test/ui/auxiliary/svh-a-base.rs @@ -0,0 +1,25 @@ +//! 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/src/test/ui/auxiliary/svh-b.rs b/src/test/ui/auxiliary/svh-b.rs new file mode 100644 index 00000000000..57029f70888 --- /dev/null +++ b/src/test/ui/auxiliary/svh-b.rs @@ -0,0 +1,13 @@ +//! 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/src/test/ui/auxiliary/trait_superkinds_in_metadata.rs b/src/test/ui/auxiliary/trait_superkinds_in_metadata.rs new file mode 100644 index 00000000000..acfd1e13e93 --- /dev/null +++ b/src/test/ui/auxiliary/trait_superkinds_in_metadata.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/auxiliary/typeid-intrinsic-aux1.rs b/src/test/ui/auxiliary/typeid-intrinsic-aux1.rs new file mode 100644 index 00000000000..281c079682f --- /dev/null +++ b/src/test/ui/auxiliary/typeid-intrinsic-aux1.rs @@ -0,0 +1,29 @@ +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/src/test/ui/auxiliary/typeid-intrinsic-aux2.rs b/src/test/ui/auxiliary/typeid-intrinsic-aux2.rs new file mode 100644 index 00000000000..281c079682f --- /dev/null +++ b/src/test/ui/auxiliary/typeid-intrinsic-aux2.rs @@ -0,0 +1,29 @@ +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/src/test/ui/auxiliary/using-target-feature-unstable.rs b/src/test/ui/auxiliary/using-target-feature-unstable.rs new file mode 100644 index 00000000000..78645c284f1 --- /dev/null +++ b/src/test/ui/auxiliary/using-target-feature-unstable.rs @@ -0,0 +1,5 @@ +#![feature(mmx_target_feature)] + +#[inline] +#[target_feature(enable = "mmx")] +pub unsafe fn foo() {} diff --git a/src/test/ui/backtrace-debuginfo-aux.rs b/src/test/ui/backtrace-debuginfo-aux.rs new file mode 100644 index 00000000000..1411bcf89e8 --- /dev/null +++ b/src/test/ui/backtrace-debuginfo-aux.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/backtrace-debuginfo.rs b/src/test/ui/backtrace-debuginfo.rs new file mode 100644 index 00000000000..8668ec82bfd --- /dev/null +++ b/src/test/ui/backtrace-debuginfo.rs @@ -0,0 +1,180 @@ +// 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-msvc issue #62844 +// 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. + if cfg!(any(target_os = "android", + all(target_os = "linux", target_arch = "arm"), + 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/src/test/ui/backtrace.rs b/src/test/ui/backtrace.rs new file mode 100644 index 00000000000..82519332d64 --- /dev/null +++ b/src/test/ui/backtrace.rs @@ -0,0 +1,125 @@ +// 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-msvc issue #62844 +// ignore-sgx no processes +// 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/src/test/ui/bare-fn-implements-fn-mut.rs b/src/test/ui/bare-fn-implements-fn-mut.rs new file mode 100644 index 00000000000..dfead48893e --- /dev/null +++ b/src/test/ui/bare-fn-implements-fn-mut.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/bare-static-string.rs b/src/test/ui/bare-static-string.rs new file mode 100644 index 00000000000..d336dc7c6a0 --- /dev/null +++ b/src/test/ui/bare-static-string.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + let x: &'static str = "foo"; + println!("{}", x); +} diff --git a/src/test/ui/bench/issue-32062.rs b/src/test/ui/bench/issue-32062.rs new file mode 100644 index 00000000000..dc45061da5b --- /dev/null +++ b/src/test/ui/bench/issue-32062.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/big-literals.rs b/src/test/ui/big-literals.rs new file mode 100644 index 00000000000..131de5439b7 --- /dev/null +++ b/src/test/ui/big-literals.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binary-minus-without-space.rs b/src/test/ui/binary-minus-without-space.rs new file mode 100644 index 00000000000..2fbd5300dd1 --- /dev/null +++ b/src/test/ui/binary-minus-without-space.rs @@ -0,0 +1,8 @@ +// run-pass +// Check that issue #954 stays fixed + + +pub fn main() { + match -1 { -1 => {}, _ => panic!("wat") } + assert_eq!(1-1, 0); +} diff --git a/src/test/ui/bind-by-move.rs b/src/test/ui/bind-by-move.rs new file mode 100644 index 00000000000..f0a9ebdd08c --- /dev/null +++ b/src/test/ui/bind-by-move.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/bind-field-short-with-modifiers.rs b/src/test/ui/binding/bind-field-short-with-modifiers.rs new file mode 100644 index 00000000000..b271f84e9ce --- /dev/null +++ b/src/test/ui/binding/bind-field-short-with-modifiers.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/binding/borrowed-ptr-pattern-2.rs b/src/test/ui/binding/borrowed-ptr-pattern-2.rs new file mode 100644 index 00000000000..40df85b1479 --- /dev/null +++ b/src/test/ui/binding/borrowed-ptr-pattern-2.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/borrowed-ptr-pattern-3.rs b/src/test/ui/binding/borrowed-ptr-pattern-3.rs new file mode 100644 index 00000000000..f2607eee815 --- /dev/null +++ b/src/test/ui/binding/borrowed-ptr-pattern-3.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/borrowed-ptr-pattern-infallible.rs b/src/test/ui/binding/borrowed-ptr-pattern-infallible.rs new file mode 100644 index 00000000000..1bbc03e19ba --- /dev/null +++ b/src/test/ui/binding/borrowed-ptr-pattern-infallible.rs @@ -0,0 +1,8 @@ +// run-pass + + +pub fn main() { + let (&x, &y) = (&3, &'a'); + assert_eq!(x, 3); + assert_eq!(y, 'a'); +} diff --git a/src/test/ui/binding/borrowed-ptr-pattern-option.rs b/src/test/ui/binding/borrowed-ptr-pattern-option.rs new file mode 100644 index 00000000000..319b8631e8d --- /dev/null +++ b/src/test/ui/binding/borrowed-ptr-pattern-option.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/binding/borrowed-ptr-pattern.rs b/src/test/ui/binding/borrowed-ptr-pattern.rs new file mode 100644 index 00000000000..d5f94ab54e3 --- /dev/null +++ b/src/test/ui/binding/borrowed-ptr-pattern.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs new file mode 100644 index 00000000000..2b8b1b29df8 --- /dev/null +++ b/src/test/ui/binding/empty-types-in-patterns.rs @@ -0,0 +1,58 @@ +// run-pass +#![feature(never_type)] +#![feature(exhaustive_patterns)] +#![feature(slice_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/src/test/ui/binding/exhaustive-bool-match-sanity.rs b/src/test/ui/binding/exhaustive-bool-match-sanity.rs new file mode 100644 index 00000000000..f83def21060 --- /dev/null +++ b/src/test/ui/binding/exhaustive-bool-match-sanity.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/binding/expr-match-generic-unique1.rs b/src/test/ui/binding/expr-match-generic-unique1.rs new file mode 100644 index 00000000000..5a5f75eea36 --- /dev/null +++ b/src/test/ui/binding/expr-match-generic-unique1.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/binding/expr-match-generic-unique2.rs b/src/test/ui/binding/expr-match-generic-unique2.rs new file mode 100644 index 00000000000..1d236135cdb --- /dev/null +++ b/src/test/ui/binding/expr-match-generic-unique2.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/expr-match-generic.rs b/src/test/ui/binding/expr-match-generic.rs new file mode 100644 index 00000000000..530fc676f7c --- /dev/null +++ b/src/test/ui/binding/expr-match-generic.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/binding/expr-match-panic-all.rs b/src/test/ui/binding/expr-match-panic-all.rs new file mode 100644 index 00000000000..ac31b49a1e9 --- /dev/null +++ b/src/test/ui/binding/expr-match-panic-all.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/expr-match-panic.rs b/src/test/ui/binding/expr-match-panic.rs new file mode 100644 index 00000000000..4b6b6e072c0 --- /dev/null +++ b/src/test/ui/binding/expr-match-panic.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/expr-match-unique.rs b/src/test/ui/binding/expr-match-unique.rs new file mode 100644 index 00000000000..a999541207d --- /dev/null +++ b/src/test/ui/binding/expr-match-unique.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/binding/expr-match.rs b/src/test/ui/binding/expr-match.rs new file mode 100644 index 00000000000..575b38fbc95 --- /dev/null +++ b/src/test/ui/binding/expr-match.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/binding/fat-arrow-match.rs b/src/test/ui/binding/fat-arrow-match.rs new file mode 100644 index 00000000000..aaf5be8cf74 --- /dev/null +++ b/src/test/ui/binding/fat-arrow-match.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs new file mode 100644 index 00000000000..ea4a9e5afa5 --- /dev/null +++ b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs @@ -0,0 +1,69 @@ +// 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/src/test/ui/binding/fn-pattern-expected-type-2.rs b/src/test/ui/binding/fn-pattern-expected-type-2.rs new file mode 100644 index 00000000000..130ff3d4465 --- /dev/null +++ b/src/test/ui/binding/fn-pattern-expected-type-2.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/binding/fn-pattern-expected-type.rs b/src/test/ui/binding/fn-pattern-expected-type.rs new file mode 100644 index 00000000000..faeb7649636 --- /dev/null +++ b/src/test/ui/binding/fn-pattern-expected-type.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/binding/func-arg-incomplete-pattern.rs b/src/test/ui/binding/func-arg-incomplete-pattern.rs new file mode 100644 index 00000000000..98dd51811de --- /dev/null +++ b/src/test/ui/binding/func-arg-incomplete-pattern.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/binding/func-arg-ref-pattern.rs b/src/test/ui/binding/func-arg-ref-pattern.rs new file mode 100644 index 00000000000..ebb7a6afa9b --- /dev/null +++ b/src/test/ui/binding/func-arg-ref-pattern.rs @@ -0,0 +1,28 @@ +// run-pass +// exec-env:RUST_POISON_ON_FREE=1 + +// 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/src/test/ui/binding/func-arg-wild-pattern.rs b/src/test/ui/binding/func-arg-wild-pattern.rs new file mode 100644 index 00000000000..bcd82c679a5 --- /dev/null +++ b/src/test/ui/binding/func-arg-wild-pattern.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/if-let.rs b/src/test/ui/binding/if-let.rs new file mode 100644 index 00000000000..3ea8d402a3e --- /dev/null +++ b/src/test/ui/binding/if-let.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/binding/inconsistent-lifetime-mismatch.rs b/src/test/ui/binding/inconsistent-lifetime-mismatch.rs new file mode 100644 index 00000000000..87768c28cf4 --- /dev/null +++ b/src/test/ui/binding/inconsistent-lifetime-mismatch.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/binding/inferred-suffix-in-pattern-range.rs b/src/test/ui/binding/inferred-suffix-in-pattern-range.rs new file mode 100644 index 00000000000..079cc0a16db --- /dev/null +++ b/src/test/ui/binding/inferred-suffix-in-pattern-range.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs new file mode 100644 index 00000000000..733e6b7b57f --- /dev/null +++ b/src/test/ui/binding/irrefutable-slice-patterns.rs @@ -0,0 +1,15 @@ +// run-pass +// #47096 + +#![feature(slice_patterns)] + +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/src/test/ui/binding/let-assignability.rs b/src/test/ui/binding/let-assignability.rs new file mode 100644 index 00000000000..5bb375d285d --- /dev/null +++ b/src/test/ui/binding/let-assignability.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/let-destruct-ref.rs b/src/test/ui/binding/let-destruct-ref.rs new file mode 100644 index 00000000000..28d7294ebc8 --- /dev/null +++ b/src/test/ui/binding/let-destruct-ref.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x = 3_usize; + let ref y = x; + assert_eq!(x, *y); +} diff --git a/src/test/ui/binding/let-var-hygiene.rs b/src/test/ui/binding/let-var-hygiene.rs new file mode 100644 index 00000000000..571207bd7d6 --- /dev/null +++ b/src/test/ui/binding/let-var-hygiene.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/binding/match-arm-statics.rs b/src/test/ui/binding/match-arm-statics.rs new file mode 100644 index 00000000000..5f7e357eeb2 --- /dev/null +++ b/src/test/ui/binding/match-arm-statics.rs @@ -0,0 +1,164 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -g + +#[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/src/test/ui/binding/match-beginning-vert.rs b/src/test/ui/binding/match-beginning-vert.rs new file mode 100644 index 00000000000..79267400b28 --- /dev/null +++ b/src/test/ui/binding/match-beginning-vert.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/binding/match-borrowed_str.rs b/src/test/ui/binding/match-borrowed_str.rs new file mode 100644 index 00000000000..22782032ebf --- /dev/null +++ b/src/test/ui/binding/match-borrowed_str.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/binding/match-bot-2.rs b/src/test/ui/binding/match-bot-2.rs new file mode 100644 index 00000000000..95b3406f0b5 --- /dev/null +++ b/src/test/ui/binding/match-bot-2.rs @@ -0,0 +1,6 @@ +// 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/src/test/ui/binding/match-bot.rs b/src/test/ui/binding/match-bot.rs new file mode 100644 index 00000000000..5c4472c7aea --- /dev/null +++ b/src/test/ui/binding/match-bot.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let i: isize = + match Some::(3) { None:: => { panic!() } Some::(_) => { 5 } }; + println!("{}", i); +} diff --git a/src/test/ui/binding/match-byte-array-patterns.rs b/src/test/ui/binding/match-byte-array-patterns.rs new file mode 100644 index 00000000000..e87745705da --- /dev/null +++ b/src/test/ui/binding/match-byte-array-patterns.rs @@ -0,0 +1,45 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/binding/match-enum-struct-0.rs b/src/test/ui/binding/match-enum-struct-0.rs new file mode 100644 index 00000000000..e2623ece84c --- /dev/null +++ b/src/test/ui/binding/match-enum-struct-0.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/match-enum-struct-1.rs b/src/test/ui/binding/match-enum-struct-1.rs new file mode 100644 index 00000000000..f035432ec99 --- /dev/null +++ b/src/test/ui/binding/match-enum-struct-1.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/binding/match-implicit-copy-unique.rs b/src/test/ui/binding/match-implicit-copy-unique.rs new file mode 100644 index 00000000000..a7e8109b46c --- /dev/null +++ b/src/test/ui/binding/match-implicit-copy-unique.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/match-in-macro.rs b/src/test/ui/binding/match-in-macro.rs new file mode 100644 index 00000000000..0840cc4404d --- /dev/null +++ b/src/test/ui/binding/match-in-macro.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/match-join.rs b/src/test/ui/binding/match-join.rs new file mode 100644 index 00000000000..60f2a458489 --- /dev/null +++ b/src/test/ui/binding/match-join.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/binding/match-larger-const.rs b/src/test/ui/binding/match-larger-const.rs new file mode 100644 index 00000000000..6f9a353207f --- /dev/null +++ b/src/test/ui/binding/match-larger-const.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/match-naked-record-expr.rs b/src/test/ui/binding/match-naked-record-expr.rs new file mode 100644 index 00000000000..c23ff8c9495 --- /dev/null +++ b/src/test/ui/binding/match-naked-record-expr.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct X { x: isize } + +pub fn main() { + let _x = match 0 { + _ => X { + x: 0 + }.x + }; +} diff --git a/src/test/ui/binding/match-naked-record.rs b/src/test/ui/binding/match-naked-record.rs new file mode 100644 index 00000000000..f7479152ebc --- /dev/null +++ b/src/test/ui/binding/match-naked-record.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/match-path.rs b/src/test/ui/binding/match-path.rs new file mode 100644 index 00000000000..286214eb8ac --- /dev/null +++ b/src/test/ui/binding/match-path.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/match-pattern-bindings.rs b/src/test/ui/binding/match-pattern-bindings.rs new file mode 100644 index 00000000000..4ec533677d6 --- /dev/null +++ b/src/test/ui/binding/match-pattern-bindings.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/binding/match-pattern-lit.rs b/src/test/ui/binding/match-pattern-lit.rs new file mode 100644 index 00000000000..c9c6135e2e6 --- /dev/null +++ b/src/test/ui/binding/match-pattern-lit.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/binding/match-pattern-no-type-params.rs b/src/test/ui/binding/match-pattern-no-type-params.rs new file mode 100644 index 00000000000..1fc7ddda023 --- /dev/null +++ b/src/test/ui/binding/match-pattern-no-type-params.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/match-pattern-simple.rs b/src/test/ui/binding/match-pattern-simple.rs new file mode 100644 index 00000000000..3f56cd4796d --- /dev/null +++ b/src/test/ui/binding/match-pattern-simple.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +fn altsimple(f: isize) { match f { _x => () } } + +pub fn main() { } diff --git a/src/test/ui/binding/match-phi.rs b/src/test/ui/binding/match-phi.rs new file mode 100644 index 00000000000..92a3f6e0f7f --- /dev/null +++ b/src/test/ui/binding/match-phi.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/binding/match-pipe-binding.rs b/src/test/ui/binding/match-pipe-binding.rs new file mode 100644 index 00000000000..7d4a7c708dd --- /dev/null +++ b/src/test/ui/binding/match-pipe-binding.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/binding/match-range-infer.rs b/src/test/ui/binding/match-range-infer.rs new file mode 100644 index 00000000000..19d1cb89d4a --- /dev/null +++ b/src/test/ui/binding/match-range-infer.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/match-range-static.rs b/src/test/ui/binding/match-range-static.rs new file mode 100644 index 00000000000..f01a3505ee6 --- /dev/null +++ b/src/test/ui/binding/match-range-static.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/match-range.rs b/src/test/ui/binding/match-range.rs new file mode 100644 index 00000000000..1dca84dfd45 --- /dev/null +++ b/src/test/ui/binding/match-range.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/binding/match-reassign.rs b/src/test/ui/binding/match-reassign.rs new file mode 100644 index 00000000000..19b48579cb4 --- /dev/null +++ b/src/test/ui/binding/match-reassign.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/binding/match-ref-binding-in-guard-3256.rs b/src/test/ui/binding/match-ref-binding-in-guard-3256.rs new file mode 100644 index 00000000000..9075a34d410 --- /dev/null +++ b/src/test/ui/binding/match-ref-binding-in-guard-3256.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/match-ref-binding-mut-option.rs b/src/test/ui/binding/match-ref-binding-mut-option.rs new file mode 100644 index 00000000000..c25639b7213 --- /dev/null +++ b/src/test/ui/binding/match-ref-binding-mut-option.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/binding/match-ref-binding-mut.rs b/src/test/ui/binding/match-ref-binding-mut.rs new file mode 100644 index 00000000000..d7afd61bc8e --- /dev/null +++ b/src/test/ui/binding/match-ref-binding-mut.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/binding/match-ref-binding.rs b/src/test/ui/binding/match-ref-binding.rs new file mode 100644 index 00000000000..ac6a07eabe1 --- /dev/null +++ b/src/test/ui/binding/match-ref-binding.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/match-ref-unsized.rs b/src/test/ui/binding/match-ref-unsized.rs new file mode 100644 index 00000000000..53784ebb9fc --- /dev/null +++ b/src/test/ui/binding/match-ref-unsized.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/binding/match-str.rs b/src/test/ui/binding/match-str.rs new file mode 100644 index 00000000000..0ee18ea18de --- /dev/null +++ b/src/test/ui/binding/match-str.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/binding/match-struct-0.rs b/src/test/ui/binding/match-struct-0.rs new file mode 100644 index 00000000000..c49f3ed6178 --- /dev/null +++ b/src/test/ui/binding/match-struct-0.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/binding/match-tag.rs b/src/test/ui/binding/match-tag.rs new file mode 100644 index 00000000000..eceb6467784 --- /dev/null +++ b/src/test/ui/binding/match-tag.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/binding/match-unique-bind.rs b/src/test/ui/binding/match-unique-bind.rs new file mode 100644 index 00000000000..f5361b118be --- /dev/null +++ b/src/test/ui/binding/match-unique-bind.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/match-unsized.rs b/src/test/ui/binding/match-unsized.rs new file mode 100644 index 00000000000..41937a557ef --- /dev/null +++ b/src/test/ui/binding/match-unsized.rs @@ -0,0 +1,9 @@ +// run-pass +fn main() { + let data: &'static str = "Hello, World!"; + match data { + &ref xs => { + assert_eq!(data, xs); + } + } +} diff --git a/src/test/ui/binding/match-value-binding-in-guard-3291.rs b/src/test/ui/binding/match-value-binding-in-guard-3291.rs new file mode 100644 index 00000000000..4b209b20a18 --- /dev/null +++ b/src/test/ui/binding/match-value-binding-in-guard-3291.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/binding/match-var-hygiene.rs b/src/test/ui/binding/match-var-hygiene.rs new file mode 100644 index 00000000000..43740bbcf1d --- /dev/null +++ b/src/test/ui/binding/match-var-hygiene.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/binding/match-vec-alternatives.rs b/src/test/ui/binding/match-vec-alternatives.rs new file mode 100644 index 00000000000..9b06a86a7b9 --- /dev/null +++ b/src/test/ui/binding/match-vec-alternatives.rs @@ -0,0 +1,81 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/binding/match-vec-rvalue.rs b/src/test/ui/binding/match-vec-rvalue.rs new file mode 100644 index 00000000000..fead2254c75 --- /dev/null +++ b/src/test/ui/binding/match-vec-rvalue.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/binding/match-with-ret-arm.rs b/src/test/ui/binding/match-with-ret-arm.rs new file mode 100644 index 00000000000..58a90964121 --- /dev/null +++ b/src/test/ui/binding/match-with-ret-arm.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/binding/multi-let.rs b/src/test/ui/binding/multi-let.rs new file mode 100644 index 00000000000..064d32a7084 --- /dev/null +++ b/src/test/ui/binding/multi-let.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x = 10; + let y = x; + assert_eq!(y, 10); +} diff --git a/src/test/ui/binding/mut-in-ident-patterns.rs b/src/test/ui/binding/mut-in-ident-patterns.rs new file mode 100644 index 00000000000..1d1dd660e51 --- /dev/null +++ b/src/test/ui/binding/mut-in-ident-patterns.rs @@ -0,0 +1,76 @@ +// 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/src/test/ui/binding/nested-exhaustive-match.rs b/src/test/ui/binding/nested-exhaustive-match.rs new file mode 100644 index 00000000000..8b2294f8432 --- /dev/null +++ b/src/test/ui/binding/nested-exhaustive-match.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/nested-matchs.rs b/src/test/ui/binding/nested-matchs.rs new file mode 100644 index 00000000000..29490fd4888 --- /dev/null +++ b/src/test/ui/binding/nested-matchs.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/binding/nested-pattern.rs b/src/test/ui/binding/nested-pattern.rs new file mode 100644 index 00000000000..7d14c9ad9b7 --- /dev/null +++ b/src/test/ui/binding/nested-pattern.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/binding/nil-pattern.rs b/src/test/ui/binding/nil-pattern.rs new file mode 100644 index 00000000000..268af351d08 --- /dev/null +++ b/src/test/ui/binding/nil-pattern.rs @@ -0,0 +1,4 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { let x = (); match x { () => { } } } diff --git a/src/test/ui/binding/nullary-or-pattern.rs b/src/test/ui/binding/nullary-or-pattern.rs new file mode 100644 index 00000000000..7a3d9d60eda --- /dev/null +++ b/src/test/ui/binding/nullary-or-pattern.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/binding/optional_comma_in_match_arm.rs b/src/test/ui/binding/optional_comma_in_match_arm.rs new file mode 100644 index 00000000000..fc268bf2a45 --- /dev/null +++ b/src/test/ui/binding/optional_comma_in_match_arm.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/binding/or-pattern.rs b/src/test/ui/binding/or-pattern.rs new file mode 100644 index 00000000000..2ab44a96c3a --- /dev/null +++ b/src/test/ui/binding/or-pattern.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/order-drop-with-match.rs b/src/test/ui/binding/order-drop-with-match.rs new file mode 100644 index 00000000000..f50632ede9f --- /dev/null +++ b/src/test/ui/binding/order-drop-with-match.rs @@ -0,0 +1,57 @@ +// 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/src/test/ui/binding/pat-ranges.rs b/src/test/ui/binding/pat-ranges.rs new file mode 100644 index 00000000000..19b3045784f --- /dev/null +++ b/src/test/ui/binding/pat-ranges.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/binding/pat-tuple-1.rs b/src/test/ui/binding/pat-tuple-1.rs new file mode 100644 index 00000000000..b09d4a22df0 --- /dev/null +++ b/src/test/ui/binding/pat-tuple-1.rs @@ -0,0 +1,93 @@ +// 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/src/test/ui/binding/pat-tuple-2.rs b/src/test/ui/binding/pat-tuple-2.rs new file mode 100644 index 00000000000..810fd264139 --- /dev/null +++ b/src/test/ui/binding/pat-tuple-2.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/binding/pat-tuple-3.rs b/src/test/ui/binding/pat-tuple-3.rs new file mode 100644 index 00000000000..9bec898611e --- /dev/null +++ b/src/test/ui/binding/pat-tuple-3.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/binding/pat-tuple-4.rs b/src/test/ui/binding/pat-tuple-4.rs new file mode 100644 index 00000000000..71a54850268 --- /dev/null +++ b/src/test/ui/binding/pat-tuple-4.rs @@ -0,0 +1,57 @@ +// 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/src/test/ui/binding/pat-tuple-5.rs b/src/test/ui/binding/pat-tuple-5.rs new file mode 100644 index 00000000000..c8cdd37dd85 --- /dev/null +++ b/src/test/ui/binding/pat-tuple-5.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/binding/pat-tuple-6.rs b/src/test/ui/binding/pat-tuple-6.rs new file mode 100644 index 00000000000..877f0e4140e --- /dev/null +++ b/src/test/ui/binding/pat-tuple-6.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/binding/pat-tuple-7.rs b/src/test/ui/binding/pat-tuple-7.rs new file mode 100644 index 00000000000..7835e2c352f --- /dev/null +++ b/src/test/ui/binding/pat-tuple-7.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + #[allow(unused_parens)] + match 0 { + (pat) => assert_eq!(pat, 0) + } +} diff --git a/src/test/ui/binding/pattern-bound-var-in-for-each.rs b/src/test/ui/binding/pattern-bound-var-in-for-each.rs new file mode 100644 index 00000000000..3f725cddc5b --- /dev/null +++ b/src/test/ui/binding/pattern-bound-var-in-for-each.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/binding/pattern-in-closure.rs b/src/test/ui/binding/pattern-in-closure.rs new file mode 100644 index 00000000000..3ac8d57681a --- /dev/null +++ b/src/test/ui/binding/pattern-in-closure.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/binding/range-inclusive-pattern-precedence.rs b/src/test/ui/binding/range-inclusive-pattern-precedence.rs new file mode 100644 index 00000000000..858239bb177 --- /dev/null +++ b/src/test/ui/binding/range-inclusive-pattern-precedence.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/binding/simple-generic-match.rs b/src/test/ui/binding/simple-generic-match.rs new file mode 100644 index 00000000000..50cfe19fef4 --- /dev/null +++ b/src/test/ui/binding/simple-generic-match.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/binding/use-uninit-match.rs b/src/test/ui/binding/use-uninit-match.rs new file mode 100644 index 00000000000..9250dbf0c43 --- /dev/null +++ b/src/test/ui/binding/use-uninit-match.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/binding/use-uninit-match2.rs b/src/test/ui/binding/use-uninit-match2.rs new file mode 100644 index 00000000000..9102730629b --- /dev/null +++ b/src/test/ui/binding/use-uninit-match2.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs new file mode 100644 index 00000000000..51e1c024bff --- /dev/null +++ b/src/test/ui/binding/zero_sized_subslice_match.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/binops-issue-22743.rs b/src/test/ui/binops-issue-22743.rs new file mode 100644 index 00000000000..393ba0a56cb --- /dev/null +++ b/src/test/ui/binops-issue-22743.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/binops.rs b/src/test/ui/binops.rs new file mode 100644 index 00000000000..a7abf6087b3 --- /dev/null +++ b/src/test/ui/binops.rs @@ -0,0 +1,89 @@ +// 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/src/test/ui/bitwise.rs b/src/test/ui/bitwise.rs new file mode 100644 index 00000000000..f79ff3c6efb --- /dev/null +++ b/src/test/ui/bitwise.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/blind-item-local-shadow.rs b/src/test/ui/blind-item-local-shadow.rs new file mode 100644 index 00000000000..942aeb6fdf4 --- /dev/null +++ b/src/test/ui/blind-item-local-shadow.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/blind-item-mixed-crate-use-item.rs b/src/test/ui/blind-item-mixed-crate-use-item.rs new file mode 100644 index 00000000000..36d8ab151e4 --- /dev/null +++ b/src/test/ui/blind-item-mixed-crate-use-item.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/blind-item-mixed-use-item.rs b/src/test/ui/blind-item-mixed-use-item.rs new file mode 100644 index 00000000000..4a39054967b --- /dev/null +++ b/src/test/ui/blind-item-mixed-use-item.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/block-arg-call-as.rs b/src/test/ui/block-arg-call-as.rs new file mode 100644 index 00000000000..87cf3a487bf --- /dev/null +++ b/src/test/ui/block-arg-call-as.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/block-arg.rs b/src/test/ui/block-arg.rs new file mode 100644 index 00000000000..bd1385e5c33 --- /dev/null +++ b/src/test/ui/block-arg.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/block-explicit-types.rs b/src/test/ui/block-explicit-types.rs new file mode 100644 index 00000000000..860fcc8df21 --- /dev/null +++ b/src/test/ui/block-explicit-types.rs @@ -0,0 +1,6 @@ +// 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/src/test/ui/block-expr-precedence.rs b/src/test/ui/block-expr-precedence.rs new file mode 100644 index 00000000000..d31eecda9bb --- /dev/null +++ b/src/test/ui/block-expr-precedence.rs @@ -0,0 +1,61 @@ +// 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; +} diff --git a/src/test/ui/block-fn-coerce.rs b/src/test/ui/block-fn-coerce.rs new file mode 100644 index 00000000000..fc5f51d46b2 --- /dev/null +++ b/src/test/ui/block-fn-coerce.rs @@ -0,0 +1,10 @@ +// run-pass + +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/src/test/ui/block-iter-1.rs b/src/test/ui/block-iter-1.rs new file mode 100644 index 00000000000..caf0266cff1 --- /dev/null +++ b/src/test/ui/block-iter-1.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/block-iter-2.rs b/src/test/ui/block-iter-2.rs new file mode 100644 index 00000000000..e90c1ee815a --- /dev/null +++ b/src/test/ui/block-iter-2.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/bool-not.rs b/src/test/ui/bool-not.rs new file mode 100644 index 00000000000..84713d6818a --- /dev/null +++ b/src/test/ui/bool-not.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + if !false { assert!((true)); } else { assert!((false)); } + if !true { assert!((false)); } else { assert!((true)); } +} diff --git a/src/test/ui/bool.rs b/src/test/ui/bool.rs new file mode 100644 index 00000000000..92f36c8fd25 --- /dev/null +++ b/src/test/ui/bool.rs @@ -0,0 +1,72 @@ +// 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/src/test/ui/borrow-by-val-method-receiver.rs b/src/test/ui/borrow-by-val-method-receiver.rs new file mode 100644 index 00000000000..465bef1614d --- /dev/null +++ b/src/test/ui/borrow-by-val-method-receiver.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/borrowck/borrowck-assign-to-subfield.rs b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs new file mode 100644 index 00000000000..050d702b625 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs b/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs new file mode 100644 index 00000000000..72bf43da95e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/borrowck/borrowck-binding-mutbl.rs b/src/test/ui/borrowck/borrowck-binding-mutbl.rs new file mode 100644 index 00000000000..c2d2e02ec15 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-binding-mutbl.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs b/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs new file mode 100644 index 00000000000..15c6e8bf210 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs new file mode 100644 index 00000000000..2839a9195a0 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs @@ -0,0 +1,21 @@ +// 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 src/librustc_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/src/test/ui/borrowck/borrowck-closures-two-imm.rs b/src/test/ui/borrowck/borrowck-closures-two-imm.rs new file mode 100644 index 00000000000..ab135194a09 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-closures-two-imm.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs b/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs new file mode 100644 index 00000000000..126323d8d24 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x = [22]; + let y = &x[0]; + assert_eq!(*y, 22); +} diff --git a/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs b/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs new file mode 100644 index 00000000000..199931d6d1e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/borrowck/borrowck-lend-args.rs b/src/test/ui/borrowck/borrowck-lend-args.rs new file mode 100644 index 00000000000..d0ef2dcdd28 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-lend-args.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs b/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs new file mode 100644 index 00000000000..628e49f574c --- /dev/null +++ b/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs b/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs new file mode 100644 index 00000000000..98e4b881893 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let bar: Box<_> = box 3; + let h = || -> isize { *bar }; + assert_eq!(h(), 3); +} diff --git a/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs new file mode 100644 index 00000000000..96d2663500e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/borrowck/borrowck-mut-uniq.rs b/src/test/ui/borrowck/borrowck-mut-uniq.rs new file mode 100644 index 00000000000..80b3484e0fb --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mut-uniq.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs b/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs new file mode 100644 index 00000000000..d2b0c01545e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/borrowck/borrowck-pat-enum.rs b/src/test/ui/borrowck/borrowck-pat-enum.rs new file mode 100644 index 00000000000..7f9c5544d0b --- /dev/null +++ b/src/test/ui/borrowck/borrowck-pat-enum.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs b/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs new file mode 100644 index 00000000000..1362fd8ce4c --- /dev/null +++ b/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/borrowck/borrowck-rvalues-mutable.rs b/src/test/ui/borrowck/borrowck-rvalues-mutable.rs new file mode 100644 index 00000000000..c4695c942e1 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-rvalues-mutable.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs b/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs new file mode 100644 index 00000000000..e89332ae31a --- /dev/null +++ b/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/borrowck/borrowck-static-item-in-fn.rs b/src/test/ui/borrowck/borrowck-static-item-in-fn.rs new file mode 100644 index 00000000000..5f4379325a5 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-static-item-in-fn.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/borrowck/borrowck-trait-lifetime.rs b/src/test/ui/borrowck/borrowck-trait-lifetime.rs new file mode 100644 index 00000000000..8a6dfe76d60 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-trait-lifetime.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/borrowck/borrowck-uniq-via-ref.rs b/src/test/ui/borrowck/borrowck-uniq-via-ref.rs new file mode 100644 index 00000000000..bdf7cc57a53 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-uniq-via-ref.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/borrowck/borrowck-univariant-enum.rs b/src/test/ui/borrowck/borrowck-univariant-enum.rs new file mode 100644 index 00000000000..c78e9475233 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-univariant-enum.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs new file mode 100644 index 00000000000..adc7dfd541f --- /dev/null +++ b/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/borrowck/borrowck-unused-mut-locals.rs b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs new file mode 100644 index 00000000000..fd0e346e2b4 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/borrowck/issue-62007-assign-box.rs b/src/test/ui/borrowck/issue-62007-assign-box.rs new file mode 100644 index 00000000000..f6fbea821b5 --- /dev/null +++ b/src/test/ui/borrowck/issue-62007-assign-box.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/borrowck/issue-62007-assign-field.rs b/src/test/ui/borrowck/issue-62007-assign-field.rs new file mode 100644 index 00000000000..5b21c083816 --- /dev/null +++ b/src/test/ui/borrowck/issue-62007-assign-field.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/borrowck/two-phase-baseline.rs b/src/test/ui/borrowck/two-phase-baseline.rs new file mode 100644 index 00000000000..994dc823dfc --- /dev/null +++ b/src/test/ui/borrowck/two-phase-baseline.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/borrowck/two-phase-bin-ops.rs b/src/test/ui/borrowck/two-phase-bin-ops.rs new file mode 100644 index 00000000000..1242ae307d3 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-bin-ops.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs b/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs new file mode 100644 index 00000000000..0b20e1945e6 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/box-new.rs b/src/test/ui/box-new.rs new file mode 100644 index 00000000000..be1a40cf779 --- /dev/null +++ b/src/test/ui/box-new.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let _a = Box::new(1); +} diff --git a/src/test/ui/bug-7183-generics.rs b/src/test/ui/bug-7183-generics.rs new file mode 100644 index 00000000000..f53a1736127 --- /dev/null +++ b/src/test/ui/bug-7183-generics.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/bug-7295.rs b/src/test/ui/bug-7295.rs new file mode 100644 index 00000000000..156ff2ee82f --- /dev/null +++ b/src/test/ui/bug-7295.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/builtin-clone-unwind.rs b/src/test/ui/builtin-clone-unwind.rs new file mode 100644 index 00000000000..339bcfa1060 --- /dev/null +++ b/src/test/ui/builtin-clone-unwind.rs @@ -0,0 +1,61 @@ +// 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/src/test/ui/builtin-clone.rs b/src/test/ui/builtin-clone.rs new file mode 100644 index 00000000000..0874d5bc390 --- /dev/null +++ b/src/test/ui/builtin-clone.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/builtin-superkinds-capabilities-transitive.rs b/src/test/ui/builtin-superkinds-capabilities-transitive.rs new file mode 100644 index 00000000000..1f997d37122 --- /dev/null +++ b/src/test/ui/builtin-superkinds-capabilities-transitive.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/builtin-superkinds-capabilities-xc.rs b/src/test/ui/builtin-superkinds-capabilities-xc.rs new file mode 100644 index 00000000000..8416bb3a377 --- /dev/null +++ b/src/test/ui/builtin-superkinds-capabilities-xc.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/builtin-superkinds-capabilities.rs b/src/test/ui/builtin-superkinds-capabilities.rs new file mode 100644 index 00000000000..e936f921a82 --- /dev/null +++ b/src/test/ui/builtin-superkinds-capabilities.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/builtin-superkinds-in-metadata.rs b/src/test/ui/builtin-superkinds-in-metadata.rs new file mode 100644 index 00000000000..117014b44ee --- /dev/null +++ b/src/test/ui/builtin-superkinds-in-metadata.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/builtin-superkinds-phantom-typaram.rs b/src/test/ui/builtin-superkinds-phantom-typaram.rs new file mode 100644 index 00000000000..9b80664b04e --- /dev/null +++ b/src/test/ui/builtin-superkinds-phantom-typaram.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/builtin-superkinds-simple.rs b/src/test/ui/builtin-superkinds-simple.rs new file mode 100644 index 00000000000..8d247715784 --- /dev/null +++ b/src/test/ui/builtin-superkinds-simple.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/builtin-superkinds-typaram.rs b/src/test/ui/builtin-superkinds-typaram.rs new file mode 100644 index 00000000000..f999dfff786 --- /dev/null +++ b/src/test/ui/builtin-superkinds-typaram.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/byte-literals.rs b/src/test/ui/byte-literals.rs new file mode 100644 index 00000000000..2649c2eac33 --- /dev/null +++ b/src/test/ui/byte-literals.rs @@ -0,0 +1,67 @@ +// 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/src/test/ui/c-stack-as-value.rs b/src/test/ui/c-stack-as-value.rs new file mode 100644 index 00000000000..7595b76fb3f --- /dev/null +++ b/src/test/ui/c-stack-as-value.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/c-stack-returning-int64.rs b/src/test/ui/c-stack-returning-int64.rs new file mode 100644 index 00000000000..388d280b831 --- /dev/null +++ b/src/test/ui/c-stack-returning-int64.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/cabi-int-widening.rs b/src/test/ui/cabi-int-widening.rs new file mode 100644 index 00000000000..240eaebf3d6 --- /dev/null +++ b/src/test/ui/cabi-int-widening.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/can-copy-pod.rs b/src/test/ui/can-copy-pod.rs new file mode 100644 index 00000000000..e6c57ca3f71 --- /dev/null +++ b/src/test/ui/can-copy-pod.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs b/src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs new file mode 100644 index 00000000000..781d5c14abe --- /dev/null +++ b/src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/cast-does-fallback.rs b/src/test/ui/cast-does-fallback.rs new file mode 100644 index 00000000000..770f7a31c76 --- /dev/null +++ b/src/test/ui/cast-does-fallback.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/cast-region-to-uint.rs b/src/test/ui/cast-region-to-uint.rs new file mode 100644 index 00000000000..33ec2d27610 --- /dev/null +++ b/src/test/ui/cast-region-to-uint.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + let x: isize = 3; + println!("&x={:x}", (&x as *const isize as usize)); +} diff --git a/src/test/ui/cast-rfc0401-vtable-kinds.rs b/src/test/ui/cast-rfc0401-vtable-kinds.rs new file mode 100644 index 00000000000..249481467e6 --- /dev/null +++ b/src/test/ui/cast-rfc0401-vtable-kinds.rs @@ -0,0 +1,62 @@ +// 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/src/test/ui/cast-rfc0401.rs b/src/test/ui/cast-rfc0401.rs new file mode 100644 index 00000000000..996fa013fed --- /dev/null +++ b/src/test/ui/cast-rfc0401.rs @@ -0,0 +1,173 @@ +// 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/src/test/ui/cast-to-infer-ty.rs b/src/test/ui/cast-to-infer-ty.rs new file mode 100644 index 00000000000..053ebb621a7 --- /dev/null +++ b/src/test/ui/cast-to-infer-ty.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/cast.rs b/src/test/ui/cast.rs new file mode 100644 index 00000000000..218275c4d99 --- /dev/null +++ b/src/test/ui/cast.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/catch-unwind-bang.rs b/src/test/ui/catch-unwind-bang.rs new file mode 100644 index 00000000000..f181991713b --- /dev/null +++ b/src/test/ui/catch-unwind-bang.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/cell-does-not-clone.rs b/src/test/ui/cell-does-not-clone.rs new file mode 100644 index 00000000000..587447b54b7 --- /dev/null +++ b/src/test/ui/cell-does-not-clone.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(dead_code)] + +use std::cell::Cell; + +#[derive(Copy)] +struct Foo { + x: isize +} + +impl Clone for Foo { + fn clone(&self) -> Foo { + // Using Cell in any way should never cause clone() to be + // invoked -- after all, that would permit evil user code to + // abuse `Cell` and trigger crashes. + + panic!(); + } +} + +pub fn main() { + let x = Cell::new(Foo { x: 22 }); + let _y = x.get(); + let _z = x.clone(); +} diff --git a/src/test/ui/cfg/auxiliary/cfg_inner_static.rs b/src/test/ui/cfg/auxiliary/cfg_inner_static.rs new file mode 100644 index 00000000000..6a619a4e768 --- /dev/null +++ b/src/test/ui/cfg/auxiliary/cfg_inner_static.rs @@ -0,0 +1,7 @@ +// this used to just ICE on compiling +pub fn foo() { + if cfg!(foo) { + static a: isize = 3; + a + } else { 3 }; +} diff --git a/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs new file mode 100644 index 00000000000..1e0f5d79c0b --- /dev/null +++ b/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic +// compile-flags: --cfg foo + +#![cfg_attr(foo, crate_type="lib")] + +pub fn foo() {} diff --git a/src/test/ui/cfg/cfg-attr-cfg.rs b/src/test/ui/cfg/cfg-attr-cfg.rs new file mode 100644 index 00000000000..61794e0bfa9 --- /dev/null +++ b/src/test/ui/cfg/cfg-attr-cfg.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/cfg/cfg-attr-crate.rs b/src/test/ui/cfg/cfg-attr-crate.rs new file mode 100644 index 00000000000..1d70f2f84f2 --- /dev/null +++ b/src/test/ui/cfg/cfg-attr-crate.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/cfg/cfg-family.rs b/src/test/ui/cfg/cfg-family.rs new file mode 100644 index 00000000000..9fb7c766921 --- /dev/null +++ b/src/test/ui/cfg/cfg-family.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/cfg/cfg-in-crate-1.rs b/src/test/ui/cfg/cfg-in-crate-1.rs new file mode 100644 index 00000000000..e84300aa331 --- /dev/null +++ b/src/test/ui/cfg/cfg-in-crate-1.rs @@ -0,0 +1,5 @@ +// run-pass +// compile-flags: --cfg bar -D warnings +#![cfg(bar)] + +fn main() {} diff --git a/src/test/ui/cfg/cfg-macros-foo.rs b/src/test/ui/cfg/cfg-macros-foo.rs new file mode 100644 index 00000000000..8b112c7961b --- /dev/null +++ b/src/test/ui/cfg/cfg-macros-foo.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/cfg/cfg-macros-notfoo.rs b/src/test/ui/cfg/cfg-macros-notfoo.rs new file mode 100644 index 00000000000..292d97821cd --- /dev/null +++ b/src/test/ui/cfg/cfg-macros-notfoo.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/cfg/cfg-match-arm.rs b/src/test/ui/cfg/cfg-match-arm.rs new file mode 100644 index 00000000000..071008f9eb6 --- /dev/null +++ b/src/test/ui/cfg/cfg-match-arm.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/cfg/cfg-target-family.rs b/src/test/ui/cfg/cfg-target-family.rs new file mode 100644 index 00000000000..ecf802f7281 --- /dev/null +++ b/src/test/ui/cfg/cfg-target-family.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/cfg/cfg-target-vendor.rs b/src/test/ui/cfg/cfg-target-vendor.rs new file mode 100644 index 00000000000..7824585162e --- /dev/null +++ b/src/test/ui/cfg/cfg-target-vendor.rs @@ -0,0 +1,8 @@ +// run-pass +#[cfg(target_vendor = "unknown")] +pub fn main() { +} + +#[cfg(not(target_vendor = "unknown"))] +pub fn main() { +} diff --git a/src/test/ui/cfg/cfg_attr.rs b/src/test/ui/cfg/cfg_attr.rs new file mode 100644 index 00000000000..c959e68acf9 --- /dev/null +++ b/src/test/ui/cfg/cfg_attr.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/cfg/cfg_inner_static.rs b/src/test/ui/cfg/cfg_inner_static.rs new file mode 100644 index 00000000000..45dbbcc1084 --- /dev/null +++ b/src/test/ui/cfg/cfg_inner_static.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/cfg/cfg_stmt_expr.rs b/src/test/ui/cfg/cfg_stmt_expr.rs new file mode 100644 index 00000000000..e466ad69f72 --- /dev/null +++ b/src/test/ui/cfg/cfg_stmt_expr.rs @@ -0,0 +1,92 @@ +// 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/src/test/ui/cfg/cfgs-on-items.rs b/src/test/ui/cfg/cfgs-on-items.rs new file mode 100644 index 00000000000..9f2fc49423e --- /dev/null +++ b/src/test/ui/cfg/cfgs-on-items.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/cfg/conditional-compile-arch.rs b/src/test/ui/cfg/conditional-compile-arch.rs new file mode 100644 index 00000000000..ea3affee406 --- /dev/null +++ b/src/test/ui/cfg/conditional-compile-arch.rs @@ -0,0 +1,38 @@ +// 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() { } diff --git a/src/test/ui/cfg/conditional-compile.rs b/src/test/ui/cfg/conditional-compile.rs new file mode 100644 index 00000000000..de5bd5f07dd --- /dev/null +++ b/src/test/ui/cfg/conditional-compile.rs @@ -0,0 +1,149 @@ +// 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/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs new file mode 100644 index 00000000000..43b266b778f --- /dev/null +++ b/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs @@ -0,0 +1,6 @@ +// run-pass +// aux-build:crate-attributes-using-cfg_attr.rs + +extern crate crate_attributes_using_cfg_attr; + +pub fn main() {} diff --git a/src/test/ui/chalkify/builtin-copy-clone.rs b/src/test/ui/chalkify/builtin-copy-clone.rs new file mode 100644 index 00000000000..d403514b553 --- /dev/null +++ b/src/test/ui/chalkify/builtin-copy-clone.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs new file mode 100644 index 00000000000..44e120c1eeb --- /dev/null +++ b/src/test/ui/chalkify/inherent_impl.rs @@ -0,0 +1,42 @@ +// 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_foo(); + s.dummy_bar::(); +} diff --git a/src/test/ui/chalkify/projection.rs b/src/test/ui/chalkify/projection.rs new file mode 100644 index 00000000000..d6a8dd7a4a2 --- /dev/null +++ b/src/test/ui/chalkify/projection.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/chalkify/super_trait.rs b/src/test/ui/chalkify/super_trait.rs new file mode 100644 index 00000000000..eeff9fd9b80 --- /dev/null +++ b/src/test/ui/chalkify/super_trait.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/chalkify/trait_implied_bound.rs b/src/test/ui/chalkify/trait_implied_bound.rs new file mode 100644 index 00000000000..8a2e1cf5990 --- /dev/null +++ b/src/test/ui/chalkify/trait_implied_bound.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/chalkify/type_implied_bound.rs b/src/test/ui/chalkify/type_implied_bound.rs new file mode 100644 index 00000000000..8673f5319bd --- /dev/null +++ b/src/test/ui/chalkify/type_implied_bound.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/char.rs b/src/test/ui/char.rs new file mode 100644 index 00000000000..cfb7a37af01 --- /dev/null +++ b/src/test/ui/char.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/char_unicode.rs b/src/test/ui/char_unicode.rs new file mode 100644 index 00000000000..93e5300e36f --- /dev/null +++ b/src/test/ui/char_unicode.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(unicode_version)] + +/// Tests access to the internal Unicode Version type and value. +pub fn main() { + check(std::char::UNICODE_VERSION); +} + +pub fn check(unicode_version: std::char::UnicodeVersion) { + assert!(unicode_version.major >= 10); +} diff --git a/src/test/ui/check-static-recursion-foreign.rs b/src/test/ui/check-static-recursion-foreign.rs new file mode 100644 index 00000000000..8ca0af8e47a --- /dev/null +++ b/src/test/ui/check-static-recursion-foreign.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(dead_code)] +// 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; + +#[link_name = "check_static_recursion_foreign_helper"] +extern "C" { + #[allow(dead_code)] + static test_static: c_int; +} + +static B: &'static c_int = unsafe { &test_static }; + +pub fn main() {} diff --git a/src/test/ui/check_const-feature-gated.rs b/src/test/ui/check_const-feature-gated.rs new file mode 100644 index 00000000000..f4faab1abc2 --- /dev/null +++ b/src/test/ui/check_const-feature-gated.rs @@ -0,0 +1,7 @@ +// run-pass + +const ARR: [usize; 1] = [2]; + +fn main() { + let _ = 5 << ARR[0]; +} diff --git a/src/test/ui/child-outlives-parent.rs b/src/test/ui/child-outlives-parent.rs new file mode 100644 index 00000000000..e3a39a44bb8 --- /dev/null +++ b/src/test/ui/child-outlives-parent.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/cleanup-arm-conditional.rs b/src/test/ui/cleanup-arm-conditional.rs new file mode 100644 index 00000000000..915842f3e85 --- /dev/null +++ b/src/test/ui/cleanup-arm-conditional.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/cleanup-rvalue-during-if-and-while.rs b/src/test/ui/cleanup-rvalue-during-if-and-while.rs new file mode 100644 index 00000000000..6fecb4e76da --- /dev/null +++ b/src/test/ui/cleanup-rvalue-during-if-and-while.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/cleanup-rvalue-for-scope.rs b/src/test/ui/cleanup-rvalue-for-scope.rs new file mode 100644 index 00000000000..b6582c01fba --- /dev/null +++ b/src/test/ui/cleanup-rvalue-for-scope.rs @@ -0,0 +1,63 @@ +// 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/src/test/ui/cleanup-rvalue-scopes.rs b/src/test/ui/cleanup-rvalue-scopes.rs new file mode 100644 index 00000000000..f51f13abf79 --- /dev/null +++ b/src/test/ui/cleanup-rvalue-scopes.rs @@ -0,0 +1,131 @@ +// run-pass + +#![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/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs new file mode 100644 index 00000000000..62f8b81385a --- /dev/null +++ b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/cleanup-shortcircuit.rs b/src/test/ui/cleanup-shortcircuit.rs new file mode 100644 index 00000000000..19d774079ab --- /dev/null +++ b/src/test/ui/cleanup-shortcircuit.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/clone-with-exterior.rs b/src/test/ui/clone-with-exterior.rs new file mode 100644 index 00000000000..1ef29719267 --- /dev/null +++ b/src/test/ui/clone-with-exterior.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/close-over-big-then-small-data.rs b/src/test/ui/close-over-big-then-small-data.rs new file mode 100644 index 00000000000..40e5f500df4 --- /dev/null +++ b/src/test/ui/close-over-big-then-small-data.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/cmp-default.rs b/src/test/ui/cmp-default.rs new file mode 100644 index 00000000000..bb5c39f5cde --- /dev/null +++ b/src/test/ui/cmp-default.rs @@ -0,0 +1,73 @@ +// 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/src/test/ui/codegen-object-shim.rs b/src/test/ui/codegen-object-shim.rs new file mode 100644 index 00000000000..9a85a50ebd9 --- /dev/null +++ b/src/test/ui/codegen-object-shim.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + assert_eq!((ToString::to_string as fn(&(dyn ToString+'static)) -> String)(&"foo"), + String::from("foo")); +} diff --git a/src/test/ui/coerce/coerce-expect-unsized.rs b/src/test/ui/coerce/coerce-expect-unsized.rs new file mode 100644 index 00000000000..b44aa6ab377 --- /dev/null +++ b/src/test/ui/coerce/coerce-expect-unsized.rs @@ -0,0 +1,43 @@ +// run-pass +#![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/src/test/ui/coerce/coerce-overloaded-autoderef.rs b/src/test/ui/coerce/coerce-overloaded-autoderef.rs new file mode 100644 index 00000000000..3fe18103ef8 --- /dev/null +++ b/src/test/ui/coerce/coerce-overloaded-autoderef.rs @@ -0,0 +1,67 @@ +// run-pass +#![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/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs new file mode 100644 index 00000000000..f033e1b5d2b --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs new file mode 100644 index 00000000000..64a365229cb --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs new file mode 100644 index 00000000000..c2aaae1c73e --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs new file mode 100644 index 00000000000..9a5652acf87 --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs new file mode 100644 index 00000000000..76cd6793b3c --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs new file mode 100644 index 00000000000..e6e7c3a51aa --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs new file mode 100644 index 00000000000..2635754f14d --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs new file mode 100644 index 00000000000..c03336ea37a --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/coerce/coerce-unify-return.rs b/src/test/ui/coerce/coerce-unify-return.rs new file mode 100644 index 00000000000..95a7ee8fe0f --- /dev/null +++ b/src/test/ui/coerce/coerce-unify-return.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/coerce/coerce-unify.rs b/src/test/ui/coerce/coerce-unify.rs new file mode 100644 index 00000000000..f1818f9bb5a --- /dev/null +++ b/src/test/ui/coerce/coerce-unify.rs @@ -0,0 +1,68 @@ +// 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/src/test/ui/coerce/coerce-unsize-subtype.rs b/src/test/ui/coerce/coerce-unsize-subtype.rs new file mode 100644 index 00000000000..45b53300c5b --- /dev/null +++ b/src/test/ui/coerce/coerce-unsize-subtype.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs new file mode 100644 index 00000000000..9a191bad8b0 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs @@ -0,0 +1,31 @@ +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/src/test/ui/coherence/coherence-bigint-int.rs b/src/test/ui/coherence/coherence-bigint-int.rs new file mode 100644 index 00000000000..0c9abdc15e6 --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-int.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:coherence_lib.rs +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] + +// 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/src/test/ui/coherence/coherence-bigint-vecint.rs b/src/test/ui/coherence/coherence-bigint-vecint.rs new file mode 100644 index 00000000000..38e0be0aa9a --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-vecint.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:coherence_lib.rs +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] + +// 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/src/test/ui/coherence/coherence-blanket.rs b/src/test/ui/coherence/coherence-blanket.rs new file mode 100644 index 00000000000..5d310cc2c6a --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:coherence_lib.rs +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] + +// 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/src/test/ui/coherence/coherence-covered-type-parameter.rs b/src/test/ui/coherence/coherence-covered-type-parameter.rs new file mode 100644 index 00000000000..1cf039f0831 --- /dev/null +++ b/src/test/ui/coherence/coherence-covered-type-parameter.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] + +// 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/src/test/ui/coherence/coherence-impl-in-fn.rs b/src/test/ui/coherence/coherence-impl-in-fn.rs new file mode 100644 index 00000000000..09e2c1e5a4e --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-in-fn.rs @@ -0,0 +1,17 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +#![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/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs new file mode 100644 index 00000000000..051cc280b2d --- /dev/null +++ b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs @@ -0,0 +1,17 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +#![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/src/test/ui/coherence/coherence-iterator-vec.rs b/src/test/ui/coherence/coherence-iterator-vec.rs new file mode 100644 index 00000000000..df6e808f7de --- /dev/null +++ b/src/test/ui/coherence/coherence-iterator-vec.rs @@ -0,0 +1,17 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +#![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/src/test/ui/coherence/coherence-multidispatch-tuple.rs b/src/test/ui/coherence/coherence-multidispatch-tuple.rs new file mode 100644 index 00000000000..6a816664c48 --- /dev/null +++ b/src/test/ui/coherence/coherence-multidispatch-tuple.rs @@ -0,0 +1,27 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +#![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/src/test/ui/coherence/coherence-rfc447-constrained.rs b/src/test/ui/coherence/coherence-rfc447-constrained.rs new file mode 100644 index 00000000000..4da54d386fd --- /dev/null +++ b/src/test/ui/coherence/coherence-rfc447-constrained.rs @@ -0,0 +1,25 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +// 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/src/test/ui/coherence/coherence-where-clause.rs b/src/test/ui/coherence/coherence-where-clause.rs new file mode 100644 index 00000000000..28397420385 --- /dev/null +++ b/src/test/ui/coherence/coherence-where-clause.rs @@ -0,0 +1,41 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] + +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/src/test/ui/coherence/coherence_copy_like.rs b/src/test/ui/coherence/coherence_copy_like.rs new file mode 100644 index 00000000000..653f76264c1 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like.rs @@ -0,0 +1,22 @@ +// run-pass +// revisions: old re + +#![cfg_attr(re, feature(re_rebalance_coherence))] +#![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/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs new file mode 100644 index 00000000000..3df6114f62a --- /dev/null +++ b/src/test/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)] +#![feature(re_rebalance_coherence)] +// 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/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs new file mode 100644 index 00000000000..e01b0dfa14d --- /dev/null +++ b/src/test/ui/collections-const-new.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(dead_code)] +// Test several functions can be used for constants +// 1. Vec::new() +// 2. String::new() + +#![feature(const_vec_new)] +#![feature(const_string_new)] + +const MY_VEC: Vec = Vec::new(); + +const MY_STRING: String = String::new(); + +pub fn main() {} diff --git a/src/test/ui/command-exec.rs b/src/test/ui/command-exec.rs new file mode 100644 index 00000000000..568be67abe3 --- /dev/null +++ b/src/test/ui/command-exec.rs @@ -0,0 +1,104 @@ +// 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/src/test/ui/command-pre-exec.rs b/src/test/ui/command-pre-exec.rs new file mode 100644 index 00000000000..c0fc554183a --- /dev/null +++ b/src/test/ui/command-pre-exec.rs @@ -0,0 +1,118 @@ +// 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/src/test/ui/command-uid-gid.rs b/src/test/ui/command-uid-gid.rs new file mode 100644 index 00000000000..f867106c35d --- /dev/null +++ b/src/test/ui/command-uid-gid.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/complex.rs b/src/test/ui/complex.rs new file mode 100644 index 00000000000..9b11ca67e47 --- /dev/null +++ b/src/test/ui/complex.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/consts/assoc-const.rs b/src/test/ui/consts/assoc-const.rs new file mode 100644 index 00000000000..b70479d255b --- /dev/null +++ b/src/test/ui/consts/assoc-const.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 00000000000..948b5e688eb --- /dev/null +++ b/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![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/src/test/ui/consts/auxiliary/cci_borrow_lib.rs b/src/test/ui/consts/auxiliary/cci_borrow_lib.rs new file mode 100644 index 00000000000..7c57a1c6678 --- /dev/null +++ b/src/test/ui/consts/auxiliary/cci_borrow_lib.rs @@ -0,0 +1,3 @@ +pub fn foo(x: &usize) -> usize { + *x +} diff --git a/src/test/ui/consts/auxiliary/cci_const.rs b/src/test/ui/consts/auxiliary/cci_const.rs new file mode 100644 index 00000000000..af6a5ad8ed3 --- /dev/null +++ b/src/test/ui/consts/auxiliary/cci_const.rs @@ -0,0 +1,6 @@ +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/src/test/ui/consts/auxiliary/cci_const_block.rs b/src/test/ui/consts/auxiliary/cci_const_block.rs new file mode 100644 index 00000000000..ad618aab830 --- /dev/null +++ b/src/test/ui/consts/auxiliary/cci_const_block.rs @@ -0,0 +1,6 @@ +pub static BLOCK_FN_DEF: fn(usize) -> usize = { + fn foo(a: usize) -> usize { + a + 10 + } + foo +}; diff --git a/src/test/ui/consts/bswap-const.rs b/src/test/ui/consts/bswap-const.rs new file mode 100644 index 00000000000..3145c21acc9 --- /dev/null +++ b/src/test/ui/consts/bswap-const.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/chained-constants-stackoverflow.rs b/src/test/ui/consts/chained-constants-stackoverflow.rs new file mode 100644 index 00000000000..a171567c5d2 --- /dev/null +++ b/src/test/ui/consts/chained-constants-stackoverflow.rs @@ -0,0 +1,356 @@ +// 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/src/test/ui/consts/const-adt-align-mismatch.rs b/src/test/ui/consts/const-adt-align-mismatch.rs new file mode 100644 index 00000000000..bd51bc9f215 --- /dev/null +++ b/src/test/ui/consts/const-adt-align-mismatch.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/consts/const-autoderef.rs b/src/test/ui/consts/const-autoderef.rs new file mode 100644 index 00000000000..1c836318d32 --- /dev/null +++ b/src/test/ui/consts/const-autoderef.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/consts/const-big-enum.rs b/src/test/ui/consts/const-big-enum.rs new file mode 100644 index 00000000000..2f21e8a6ddd --- /dev/null +++ b/src/test/ui/consts/const-big-enum.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/consts/const-binops.rs b/src/test/ui/consts/const-binops.rs new file mode 100644 index 00000000000..d038dfeb419 --- /dev/null +++ b/src/test/ui/consts/const-binops.rs @@ -0,0 +1,126 @@ +// 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/src/test/ui/consts/const-bitshift-rhs-inference.rs b/src/test/ui/consts/const-bitshift-rhs-inference.rs new file mode 100644 index 00000000000..cf21c296cf3 --- /dev/null +++ b/src/test/ui/consts/const-bitshift-rhs-inference.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/consts/const-block-cross-crate-fn.rs b/src/test/ui/consts/const-block-cross-crate-fn.rs new file mode 100644 index 00000000000..0ac3830d230 --- /dev/null +++ b/src/test/ui/consts/const-block-cross-crate-fn.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/consts/const-block-item-macro-codegen.rs b/src/test/ui/consts/const-block-item-macro-codegen.rs new file mode 100644 index 00000000000..7ad883686ae --- /dev/null +++ b/src/test/ui/consts/const-block-item-macro-codegen.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/consts/const-block-item.rs b/src/test/ui/consts/const-block-item.rs new file mode 100644 index 00000000000..cf0d4441d4a --- /dev/null +++ b/src/test/ui/consts/const-block-item.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs new file mode 100644 index 00000000000..10a4c31f24e --- /dev/null +++ b/src/test/ui/consts/const-block-non-item-statement-3.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(dead_code)] + +type Array = [u32; { let x = 2; 5 }]; + +pub fn main() { + let _: Array = [0; 5]; +} diff --git a/src/test/ui/consts/const-block.rs b/src/test/ui/consts/const-block.rs new file mode 100644 index 00000000000..7172a34c8cf --- /dev/null +++ b/src/test/ui/consts/const-block.rs @@ -0,0 +1,45 @@ +// run-pass + +#![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/src/test/ui/consts/const-bound.rs b/src/test/ui/consts/const-bound.rs new file mode 100644 index 00000000000..735056a0ab0 --- /dev/null +++ b/src/test/ui/consts/const-bound.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/consts/const-byte-str-cast.rs b/src/test/ui/consts/const-byte-str-cast.rs new file mode 100644 index 00000000000..65d626c297f --- /dev/null +++ b/src/test/ui/consts/const-byte-str-cast.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/consts/const-cast-ptr-int.rs b/src/test/ui/consts/const-cast-ptr-int.rs new file mode 100644 index 00000000000..987d9616e91 --- /dev/null +++ b/src/test/ui/consts/const-cast-ptr-int.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-cast.rs b/src/test/ui/consts/const-cast.rs new file mode 100644 index 00000000000..0d8609e334a --- /dev/null +++ b/src/test/ui/consts/const-cast.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-const.rs b/src/test/ui/consts/const-const.rs new file mode 100644 index 00000000000..85e4a72e86d --- /dev/null +++ b/src/test/ui/consts/const-const.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/consts/const-contents.rs b/src/test/ui/consts/const-contents.rs new file mode 100644 index 00000000000..7ba3d435650 --- /dev/null +++ b/src/test/ui/consts/const-contents.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/consts/const-cross-crate-const.rs b/src/test/ui/consts/const-cross-crate-const.rs new file mode 100644 index 00000000000..92020417ff5 --- /dev/null +++ b/src/test/ui/consts/const-cross-crate-const.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-cross-crate-extern.rs b/src/test/ui/consts/const-cross-crate-extern.rs new file mode 100644 index 00000000000..3c61afd5bec --- /dev/null +++ b/src/test/ui/consts/const-cross-crate-extern.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/consts/const-deref.rs b/src/test/ui/consts/const-deref.rs new file mode 100644 index 00000000000..6060d8e510e --- /dev/null +++ b/src/test/ui/consts/const-deref.rs @@ -0,0 +1,8 @@ +// run-pass + +const C: &'static isize = &1000; +static D: isize = *C; + +pub fn main() { + assert_eq!(D, 1000); +} diff --git a/src/test/ui/consts/const-endianess.rs b/src/test/ui/consts/const-endianess.rs new file mode 100644 index 00000000000..936f31954d3 --- /dev/null +++ b/src/test/ui/consts/const-endianess.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/consts/const-enum-byref-self.rs b/src/test/ui/consts/const-enum-byref-self.rs new file mode 100644 index 00000000000..b7e14bfb765 --- /dev/null +++ b/src/test/ui/consts/const-enum-byref-self.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/consts/const-enum-byref.rs b/src/test/ui/consts/const-enum-byref.rs new file mode 100644 index 00000000000..badf5294654 --- /dev/null +++ b/src/test/ui/consts/const-enum-byref.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-enum-cast.rs b/src/test/ui/consts/const-enum-cast.rs new file mode 100644 index 00000000000..a3255c2f601 --- /dev/null +++ b/src/test/ui/consts/const-enum-cast.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/consts/const-enum-ptr.rs b/src/test/ui/consts/const-enum-ptr.rs new file mode 100644 index 00000000000..84f4eb8406d --- /dev/null +++ b/src/test/ui/consts/const-enum-ptr.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-enum-struct.rs b/src/test/ui/consts/const-enum-struct.rs new file mode 100644 index 00000000000..ee88c936188 --- /dev/null +++ b/src/test/ui/consts/const-enum-struct.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-enum-struct2.rs b/src/test/ui/consts/const-enum-struct2.rs new file mode 100644 index 00000000000..6dfe63d5d00 --- /dev/null +++ b/src/test/ui/consts/const-enum-struct2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-enum-structlike.rs b/src/test/ui/consts/const-enum-structlike.rs new file mode 100644 index 00000000000..0ea79aebce6 --- /dev/null +++ b/src/test/ui/consts/const-enum-structlike.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-enum-tuple.rs b/src/test/ui/consts/const-enum-tuple.rs new file mode 100644 index 00000000000..e0363166b02 --- /dev/null +++ b/src/test/ui/consts/const-enum-tuple.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/consts/const-enum-tuple2.rs b/src/test/ui/consts/const-enum-tuple2.rs new file mode 100644 index 00000000000..ef378b5995d --- /dev/null +++ b/src/test/ui/consts/const-enum-tuple2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/consts/const-enum-tuplestruct.rs b/src/test/ui/consts/const-enum-tuplestruct.rs new file mode 100644 index 00000000000..f93945c6a68 --- /dev/null +++ b/src/test/ui/consts/const-enum-tuplestruct.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-enum-tuplestruct2.rs b/src/test/ui/consts/const-enum-tuplestruct2.rs new file mode 100644 index 00000000000..b8aa9a3152f --- /dev/null +++ b/src/test/ui/consts/const-enum-tuplestruct2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-enum-vec-index.rs b/src/test/ui/consts/const-enum-vec-index.rs new file mode 100644 index 00000000000..3f155340ab5 --- /dev/null +++ b/src/test/ui/consts/const-enum-vec-index.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/consts/const-enum-vec-ptr.rs b/src/test/ui/consts/const-enum-vec-ptr.rs new file mode 100644 index 00000000000..43ffe6570dc --- /dev/null +++ b/src/test/ui/consts/const-enum-vec-ptr.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/const-enum-vector.rs b/src/test/ui/consts/const-enum-vector.rs new file mode 100644 index 00000000000..ee3739f9723 --- /dev/null +++ b/src/test/ui/consts/const-enum-vector.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/const-expr-in-fixed-length-vec.rs b/src/test/ui/consts/const-expr-in-fixed-length-vec.rs new file mode 100644 index 00000000000..a9960b4552b --- /dev/null +++ b/src/test/ui/consts/const-expr-in-fixed-length-vec.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-expr-in-vec-repeat.rs b/src/test/ui/consts/const-expr-in-vec-repeat.rs new file mode 100644 index 00000000000..4eaef25059b --- /dev/null +++ b/src/test/ui/consts/const-expr-in-vec-repeat.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/consts/const-extern-function.rs b/src/test/ui/consts/const-extern-function.rs new file mode 100644 index 00000000000..cfcf99b867a --- /dev/null +++ b/src/test/ui/consts/const-extern-function.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-fields-and-indexing.rs b/src/test/ui/consts/const-fields-and-indexing.rs new file mode 100644 index 00000000000..bb13bebf4e2 --- /dev/null +++ b/src/test/ui/consts/const-fields-and-indexing.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/consts/const-fn-const-eval.rs b/src/test/ui/consts/const-fn-const-eval.rs new file mode 100644 index 00000000000..d4da990812e --- /dev/null +++ b/src/test/ui/consts/const-fn-const-eval.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/consts/const-fn-feature-flags.rs b/src/test/ui/consts/const-fn-feature-flags.rs new file mode 100644 index 00000000000..30e7e102b86 --- /dev/null +++ b/src/test/ui/consts/const-fn-feature-flags.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/consts/const-fn-method.rs b/src/test/ui/consts/const-fn-method.rs new file mode 100644 index 00000000000..002646db92a --- /dev/null +++ b/src/test/ui/consts/const-fn-method.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/consts/const-fn-nested.rs b/src/test/ui/consts/const-fn-nested.rs new file mode 100644 index 00000000000..ef5598bf9e7 --- /dev/null +++ b/src/test/ui/consts/const-fn-nested.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-fn-stability-calls.rs b/src/test/ui/consts/const-fn-stability-calls.rs new file mode 100644 index 00000000000..13867904895 --- /dev/null +++ b/src/test/ui/consts/const-fn-stability-calls.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/consts/const-fn-type-name.rs b/src/test/ui/consts/const-fn-type-name.rs new file mode 100644 index 00000000000..2bb1aeecf37 --- /dev/null +++ b/src/test/ui/consts/const-fn-type-name.rs @@ -0,0 +1,37 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(const_fn)] +#![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/src/test/ui/consts/const-fn-val.rs b/src/test/ui/consts/const-fn-val.rs new file mode 100644 index 00000000000..e5bf4757e3a --- /dev/null +++ b/src/test/ui/consts/const-fn-val.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/const-fn.rs b/src/test/ui/consts/const-fn.rs new file mode 100644 index 00000000000..7b924aa46aa --- /dev/null +++ b/src/test/ui/consts/const-fn.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/consts/const-index-feature-gate.rs b/src/test/ui/consts/const-index-feature-gate.rs new file mode 100644 index 00000000000..3537a1790cc --- /dev/null +++ b/src/test/ui/consts/const-index-feature-gate.rs @@ -0,0 +1,7 @@ +// run-pass +#![allow(dead_code)] +const ARR: [usize; 1] = [2]; +const ARR2: [i32; ARR[0]] = [5, 6]; + +fn main() { +} diff --git a/src/test/ui/consts/const-int-saturating-arith.rs b/src/test/ui/consts/const-int-saturating-arith.rs new file mode 100644 index 00000000000..394d6c17f5a --- /dev/null +++ b/src/test/ui/consts/const-int-saturating-arith.rs @@ -0,0 +1,35 @@ +// run-pass +// ignore-emscripten no i128 support +#![feature(const_saturating_int_methods)] + +const INT_U32_NO: u32 = (42 as u32).saturating_add(2); +const INT_U32: u32 = u32::max_value().saturating_add(1); +const INT_U128: u128 = u128::max_value().saturating_add(1); +const INT_I128: i128 = i128::max_value().saturating_add(1); +const INT_I128_NEG: i128 = i128::min_value().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_value().saturating_sub(1); +const INT_I32_POS_SUB: i32 = i32::max_value().saturating_sub(-1); +const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1); +const INT_I128_NEG_SUB: i128 = i128::min_value().saturating_sub(1); +const INT_I128_POS_SUB: i128 = i128::max_value().saturating_sub(-1); + +fn main() { + assert_eq!(INT_U32_NO, 44); + assert_eq!(INT_U32, u32::max_value()); + assert_eq!(INT_U128, u128::max_value()); + assert_eq!(INT_I128, i128::max_value()); + assert_eq!(INT_I128_NEG, i128::min_value()); + + 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_value()); + assert_eq!(INT_I32_POS_SUB, i32::max_value()); + assert_eq!(INT_U128_SUB, 0); + assert_eq!(INT_I128_NEG_SUB, i128::min_value()); + assert_eq!(INT_I128_POS_SUB, i128::max_value()); +} diff --git a/src/test/ui/consts/const-meth-pattern.rs b/src/test/ui/consts/const-meth-pattern.rs new file mode 100644 index 00000000000..1544d760a13 --- /dev/null +++ b/src/test/ui/consts/const-meth-pattern.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/consts/const-needs_drop.rs b/src/test/ui/consts/const-needs_drop.rs new file mode 100644 index 00000000000..58e80116442 --- /dev/null +++ b/src/test/ui/consts/const-needs_drop.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/consts/const-negation.rs b/src/test/ui/consts/const-negation.rs new file mode 100644 index 00000000000..1c8e27ae617 --- /dev/null +++ b/src/test/ui/consts/const-negation.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/consts/const-negative.rs b/src/test/ui/consts/const-negative.rs new file mode 100644 index 00000000000..1cb56093628 --- /dev/null +++ b/src/test/ui/consts/const-negative.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/consts/const-nullary-enum.rs b/src/test/ui/consts/const-nullary-enum.rs new file mode 100644 index 00000000000..b6574dce6ca --- /dev/null +++ b/src/test/ui/consts/const-nullary-enum.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/consts/const-nullary-univariant-enum.rs b/src/test/ui/consts/const-nullary-univariant-enum.rs new file mode 100644 index 00000000000..51349ad3195 --- /dev/null +++ b/src/test/ui/consts/const-nullary-univariant-enum.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/const-pattern-variant.rs b/src/test/ui/consts/const-pattern-variant.rs new file mode 100644 index 00000000000..80f749ed72d --- /dev/null +++ b/src/test/ui/consts/const-pattern-variant.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/consts/const-rec-and-tup.rs b/src/test/ui/consts/const-rec-and-tup.rs new file mode 100644 index 00000000000..0bddaf75de8 --- /dev/null +++ b/src/test/ui/consts/const-rec-and-tup.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/consts/const-region-ptrs-noncopy.rs b/src/test/ui/consts/const-region-ptrs-noncopy.rs new file mode 100644 index 00000000000..10b9ce896a6 --- /dev/null +++ b/src/test/ui/consts/const-region-ptrs-noncopy.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/const-region-ptrs.rs b/src/test/ui/consts/const-region-ptrs.rs new file mode 100644 index 00000000000..9b94a2b1121 --- /dev/null +++ b/src/test/ui/consts/const-region-ptrs.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/consts/const-repeated-values.rs b/src/test/ui/consts/const-repeated-values.rs new file mode 100644 index 00000000000..27efb5ba2a2 --- /dev/null +++ b/src/test/ui/consts/const-repeated-values.rs @@ -0,0 +1,10 @@ +// run-pass +const FOO: isize = 42; + +enum Bar { + Boo = *[&FOO; 4][3], +} + +fn main() { + assert_eq!(Bar::Boo as isize, 42); +} diff --git a/src/test/ui/consts/const-size_of-align_of.rs b/src/test/ui/consts/const-size_of-align_of.rs new file mode 100644 index 00000000000..0c63dc84a37 --- /dev/null +++ b/src/test/ui/consts/const-size_of-align_of.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/consts/const-str-ptr.rs b/src/test/ui/consts/const-str-ptr.rs new file mode 100644 index 00000000000..56fd9d9f55f --- /dev/null +++ b/src/test/ui/consts/const-str-ptr.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/consts/const-struct-offsets.rs b/src/test/ui/consts/const-struct-offsets.rs new file mode 100644 index 00000000000..26a00832079 --- /dev/null +++ b/src/test/ui/consts/const-struct-offsets.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/consts/const-struct.rs b/src/test/ui/consts/const-struct.rs new file mode 100644 index 00000000000..db397a891d6 --- /dev/null +++ b/src/test/ui/consts/const-struct.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/consts/const-trait-to-trait.rs b/src/test/ui/consts/const-trait-to-trait.rs new file mode 100644 index 00000000000..12a2999d79d --- /dev/null +++ b/src/test/ui/consts/const-trait-to-trait.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/consts/const-tuple-struct.rs b/src/test/ui/consts/const-tuple-struct.rs new file mode 100644 index 00000000000..0144afaaceb --- /dev/null +++ b/src/test/ui/consts/const-tuple-struct.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/consts/const-unit-struct.rs b/src/test/ui/consts/const-unit-struct.rs new file mode 100644 index 00000000000..1c9e0e8d3c9 --- /dev/null +++ b/src/test/ui/consts/const-unit-struct.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct Foo; + +static X: Foo = Foo; + +pub fn main() { + match X { + Foo => {} + } +} diff --git a/src/test/ui/consts/const-unsafe-fn.rs b/src/test/ui/consts/const-unsafe-fn.rs new file mode 100644 index 00000000000..72ce73f745f --- /dev/null +++ b/src/test/ui/consts/const-unsafe-fn.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/consts/const-vec-of-fns.rs b/src/test/ui/consts/const-vec-of-fns.rs new file mode 100644 index 00000000000..6d90b066b74 --- /dev/null +++ b/src/test/ui/consts/const-vec-of-fns.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/consts/const-vec-syntax.rs b/src/test/ui/consts/const-vec-syntax.rs new file mode 100644 index 00000000000..61246e44eba --- /dev/null +++ b/src/test/ui/consts/const-vec-syntax.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_: &[isize]) {} + +pub fn main() { + let v = [ 1, 2, 3 ]; + f(&v); +} diff --git a/src/test/ui/consts/const-vecs-and-slices.rs b/src/test/ui/consts/const-vecs-and-slices.rs new file mode 100644 index 00000000000..1cdc33b7a34 --- /dev/null +++ b/src/test/ui/consts/const-vecs-and-slices.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/consts/const.rs b/src/test/ui/consts/const.rs new file mode 100644 index 00000000000..71fbadfa828 --- /dev/null +++ b/src/test/ui/consts/const.rs @@ -0,0 +1,6 @@ +// run-pass +#![allow(non_upper_case_globals)] + +static i: isize = 10; + +pub fn main() { println!("{}", i); } diff --git a/src/test/ui/consts/consts-in-patterns.rs b/src/test/ui/consts/consts-in-patterns.rs new file mode 100644 index 00000000000..ac6c5a51506 --- /dev/null +++ b/src/test/ui/consts/consts-in-patterns.rs @@ -0,0 +1,18 @@ +// run-pass + +const FOO: isize = 10; +const BAR: isize = 3; + +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); +} diff --git a/src/test/ui/consts/deref_in_pattern.rs b/src/test/ui/consts/deref_in_pattern.rs new file mode 100644 index 00000000000..cc47b5b49c0 --- /dev/null +++ b/src/test/ui/consts/deref_in_pattern.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/ice-48279.rs b/src/test/ui/consts/ice-48279.rs new file mode 100644 index 00000000000..d1d90df240c --- /dev/null +++ b/src/test/ui/consts/ice-48279.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/consts/issue-37550.rs b/src/test/ui/consts/issue-37550.rs new file mode 100644 index 00000000000..04865830df2 --- /dev/null +++ b/src/test/ui/consts/issue-37550.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +#![feature(const_fn)] + +const fn x() { + let t = true; + let x = || t; +} + +fn main() {} diff --git a/src/test/ui/consts/issue-broken-mir.rs b/src/test/ui/consts/issue-broken-mir.rs new file mode 100644 index 00000000000..36f0ff92104 --- /dev/null +++ b/src/test/ui/consts/issue-broken-mir.rs @@ -0,0 +1,10 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/27918 + +fn main() { + match b" " { + b"1234" => {}, + _ => {}, + } +} diff --git a/src/test/ui/consts/locals-in-const-fn.rs b/src/test/ui/consts/locals-in-const-fn.rs new file mode 100644 index 00000000000..95d50171a84 --- /dev/null +++ b/src/test/ui/consts/locals-in-const-fn.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/consts/match-const-fn-structs.rs b/src/test/ui/consts/match-const-fn-structs.rs new file mode 100644 index 00000000000..5a68048c477 --- /dev/null +++ b/src/test/ui/consts/match-const-fn-structs.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/consts/mozjs-error.rs b/src/test/ui/consts/mozjs-error.rs new file mode 100644 index 00000000000..7edcadbf2cb --- /dev/null +++ b/src/test/ui/consts/mozjs-error.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/consts/non-scalar-cast.rs b/src/test/ui/consts/non-scalar-cast.rs new file mode 100644 index 00000000000..671366c90ec --- /dev/null +++ b/src/test/ui/consts/non-scalar-cast.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/consts/promotion.rs b/src/test/ui/consts/promotion.rs new file mode 100644 index 00000000000..3c5401e4212 --- /dev/null +++ b/src/test/ui/consts/promotion.rs @@ -0,0 +1,17 @@ +// run-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/src/test/ui/consts/references.rs b/src/test/ui/consts/references.rs new file mode 100644 index 00000000000..d0af47a8ea8 --- /dev/null +++ b/src/test/ui/consts/references.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/consts/repeat_match.rs b/src/test/ui/consts/repeat_match.rs new file mode 100644 index 00000000000..20983184a47 --- /dev/null +++ b/src/test/ui/consts/repeat_match.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/consts/return-in-const-fn.rs b/src/test/ui/consts/return-in-const-fn.rs new file mode 100644 index 00000000000..077a33c081b --- /dev/null +++ b/src/test/ui/consts/return-in-const-fn.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/consts/signed_enum_discr.rs b/src/test/ui/consts/signed_enum_discr.rs new file mode 100644 index 00000000000..2e4395ccf22 --- /dev/null +++ b/src/test/ui/consts/signed_enum_discr.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/consts/transmute-const.rs b/src/test/ui/consts/transmute-const.rs new file mode 100644 index 00000000000..e24f89cdffd --- /dev/null +++ b/src/test/ui/consts/transmute-const.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(const_transmute)] + +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/src/test/ui/consts/tuple-struct-constructors.rs b/src/test/ui/consts/tuple-struct-constructors.rs new file mode 100644 index 00000000000..1655f0eb850 --- /dev/null +++ b/src/test/ui/consts/tuple-struct-constructors.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/core-run-destroy.rs b/src/test/ui/core-run-destroy.rs new file mode 100644 index 00000000000..225b2ca8f4d --- /dev/null +++ b/src/test/ui/core-run-destroy.rs @@ -0,0 +1,87 @@ +// 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 + +// 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/src/test/ui/crate-leading-sep.rs b/src/test/ui/crate-leading-sep.rs new file mode 100644 index 00000000000..ca5905fab41 --- /dev/null +++ b/src/test/ui/crate-leading-sep.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + use ::std::mem; + mem::drop(2_usize); +} diff --git a/src/test/ui/crate-method-reexport-grrrrrrr.rs b/src/test/ui/crate-method-reexport-grrrrrrr.rs new file mode 100644 index 00000000000..eefcf7738ad --- /dev/null +++ b/src/test/ui/crate-method-reexport-grrrrrrr.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/crate-name-attr-used.rs b/src/test/ui/crate-name-attr-used.rs new file mode 100644 index 00000000000..ad53a53143e --- /dev/null +++ b/src/test/ui/crate-name-attr-used.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs new file mode 100644 index 00000000000..77168be5374 --- /dev/null +++ b/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 00000000000..948b5e688eb --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![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/src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs b/src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs new file mode 100644 index 00000000000..dceec7e3ec1 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs @@ -0,0 +1,9 @@ +pub struct Foo { + pub x: isize +} + +impl Foo { + pub fn new() -> Foo { + Foo { x: 3 } + } +} diff --git a/src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs new file mode 100644 index 00000000000..7c57a1c6678 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs @@ -0,0 +1,3 @@ +pub fn foo(x: &usize) -> usize { + *x +} diff --git a/src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs b/src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs new file mode 100644 index 00000000000..4cd001ecc9e --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs @@ -0,0 +1,10 @@ +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/src/test/ui/cross-crate/auxiliary/cci_const.rs b/src/test/ui/cross-crate/auxiliary/cci_const.rs new file mode 100644 index 00000000000..af6a5ad8ed3 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_const.rs @@ -0,0 +1,6 @@ +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/src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs new file mode 100644 index 00000000000..0db0037b203 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs @@ -0,0 +1,16 @@ +#![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/src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs new file mode 100644 index 00000000000..60c36bc7d05 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs @@ -0,0 +1,11 @@ +#![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/src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs new file mode 100644 index 00000000000..379ed076611 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs @@ -0,0 +1,52 @@ +#![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/src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs new file mode 100644 index 00000000000..177dba2178f --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs @@ -0,0 +1,12 @@ +#![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/src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs b/src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs new file mode 100644 index 00000000000..7e7e3b86024 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs @@ -0,0 +1,17 @@ +#![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/src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs b/src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs new file mode 100644 index 00000000000..9d1e0742e3c --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub struct Au(pub isize); diff --git a/src/test/ui/cross-crate/auxiliary/pub_static_array.rs b/src/test/ui/cross-crate/auxiliary/pub_static_array.rs new file mode 100644 index 00000000000..49cb76921ad --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/pub_static_array.rs @@ -0,0 +1 @@ +pub static ARRAY: [u8; 1] = [1]; diff --git a/src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs b/src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs new file mode 100644 index 00000000000..cc961625f32 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs @@ -0,0 +1,43 @@ +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/src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs b/src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs new file mode 100644 index 00000000000..7c1175f7a88 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs @@ -0,0 +1,3 @@ +pub trait FromBuf<'a> { + fn from_buf(_: &'a [u8]) -> Self; +} diff --git a/src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs b/src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs new file mode 100644 index 00000000000..e79e334b53f --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs @@ -0,0 +1,8 @@ +pub fn foo() -> isize { + static a: isize = 3; + a +} + +pub fn bar() -> isize { + foo::() +} diff --git a/src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs b/src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs new file mode 100644 index 00000000000..d8a55dd34bc --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs @@ -0,0 +1,12 @@ +#![feature(associated_type_defaults)] + +pub trait Foo { + type Out: Default + ToString = T; +} + +impl Foo for () { +} + +impl Foo for () { + type Out = bool; +} diff --git a/src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs b/src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs new file mode 100644 index 00000000000..2ab23b4d7e4 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs @@ -0,0 +1,16 @@ +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/src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs b/src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs new file mode 100644 index 00000000000..e18d34799ef --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs @@ -0,0 +1,17 @@ +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/src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs b/src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs new file mode 100644 index 00000000000..69ed498e7e1 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs @@ -0,0 +1,28 @@ +#![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/src/test/ui/cross-crate/cci_borrow.rs b/src/test/ui/cross-crate/cci_borrow.rs new file mode 100644 index 00000000000..605a166ffa3 --- /dev/null +++ b/src/test/ui/cross-crate/cci_borrow.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/cross-crate/cci_capture_clause.rs b/src/test/ui/cross-crate/cci_capture_clause.rs new file mode 100644 index 00000000000..ea699b5f5ac --- /dev/null +++ b/src/test/ui/cross-crate/cci_capture_clause.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/cross-crate/cci_impl_exe.rs b/src/test/ui/cross-crate/cci_impl_exe.rs new file mode 100644 index 00000000000..b11fb23ebc8 --- /dev/null +++ b/src/test/ui/cross-crate/cci_impl_exe.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/cross-crate/cci_iter_exe.rs b/src/test/ui/cross-crate/cci_iter_exe.rs new file mode 100644 index 00000000000..8b58d90fe4e --- /dev/null +++ b/src/test/ui/cross-crate/cci_iter_exe.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/cross-crate/cci_nested_exe.rs b/src/test/ui/cross-crate/cci_nested_exe.rs new file mode 100644 index 00000000000..1c001a2a372 --- /dev/null +++ b/src/test/ui/cross-crate/cci_nested_exe.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/cross-crate/cci_no_inline_exe.rs b/src/test/ui/cross-crate/cci_no_inline_exe.rs new file mode 100644 index 00000000000..ffc701678d3 --- /dev/null +++ b/src/test/ui/cross-crate/cci_no_inline_exe.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/cross-crate/cross-crate-const-pat.rs b/src/test/ui/cross-crate/cross-crate-const-pat.rs new file mode 100644 index 00000000000..e8fa8485ab2 --- /dev/null +++ b/src/test/ui/cross-crate/cross-crate-const-pat.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs b/src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs new file mode 100644 index 00000000000..eabffc16170 --- /dev/null +++ b/src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs b/src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs new file mode 100644 index 00000000000..3881e335220 --- /dev/null +++ b/src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs b/src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs new file mode 100644 index 00000000000..8c70a1ce477 --- /dev/null +++ b/src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/cross-crate/static-array-across-crate.rs b/src/test/ui/cross-crate/static-array-across-crate.rs new file mode 100644 index 00000000000..0b84e0e6a3f --- /dev/null +++ b/src/test/ui/cross-crate/static-array-across-crate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/cross-crate/xcrate-address-insignificant.rs b/src/test/ui/cross-crate/xcrate-address-insignificant.rs new file mode 100644 index 00000000000..33c70650603 --- /dev/null +++ b/src/test/ui/cross-crate/xcrate-address-insignificant.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/cross-crate/xcrate-associated-type-defaults.rs b/src/test/ui/cross-crate/xcrate-associated-type-defaults.rs new file mode 100644 index 00000000000..0f3e077d1de --- /dev/null +++ b/src/test/ui/cross-crate/xcrate-associated-type-defaults.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/cross-crate/xcrate-static-addresses.rs b/src/test/ui/cross-crate/xcrate-static-addresses.rs new file mode 100644 index 00000000000..3c33976568e --- /dev/null +++ b/src/test/ui/cross-crate/xcrate-static-addresses.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs b/src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs new file mode 100644 index 00000000000..1fd7eb878d9 --- /dev/null +++ b/src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/cross-crate/xcrate-unit-struct.rs b/src/test/ui/cross-crate/xcrate-unit-struct.rs new file mode 100644 index 00000000000..7aa3eb0d6c4 --- /dev/null +++ b/src/test/ui/cross-crate/xcrate-unit-struct.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs b/src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs new file mode 100644 index 00000000000..4593fec5196 --- /dev/null +++ b/src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/crt-static-off-works.rs b/src/test/ui/crt-static-off-works.rs new file mode 100644 index 00000000000..911467ee54e --- /dev/null +++ b/src/test/ui/crt-static-off-works.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/crt-static-on-works.rs b/src/test/ui/crt-static-on-works.rs new file mode 100644 index 00000000000..21407b1b911 --- /dev/null +++ b/src/test/ui/crt-static-on-works.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(stable_features)] +// compile-flags:-C target-feature=+crt-static -Z unstable-options + +#![feature(cfg_target_feature)] + +#[cfg(target_feature = "crt-static")] +fn main() {} diff --git a/src/test/ui/cycle-generic-bound.rs b/src/test/ui/cycle-generic-bound.rs new file mode 100644 index 00000000000..9241f3789d7 --- /dev/null +++ b/src/test/ui/cycle-generic-bound.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/dead-code-alias-in-pat.rs b/src/test/ui/dead-code-alias-in-pat.rs new file mode 100644 index 00000000000..69d455f3b60 --- /dev/null +++ b/src/test/ui/dead-code-alias-in-pat.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/dead-code-leading-underscore.rs b/src/test/ui/dead-code-leading-underscore.rs new file mode 100644 index 00000000000..1b6e03ab887 --- /dev/null +++ b/src/test/ui/dead-code-leading-underscore.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/debuginfo-lto.rs b/src/test/ui/debuginfo-lto.rs new file mode 100644 index 00000000000..e4beee9e737 --- /dev/null +++ b/src/test/ui/debuginfo-lto.rs @@ -0,0 +1,24 @@ +// 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 + +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/src/test/ui/deep.rs b/src/test/ui/deep.rs new file mode 100644 index 00000000000..2bb109c0e3f --- /dev/null +++ b/src/test/ui/deep.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/default-alloc-error-hook.rs b/src/test/ui/default-alloc-error-hook.rs new file mode 100644 index 00000000000..40f61c2b7d5 --- /dev/null +++ b/src/test/ui/default-alloc-error-hook.rs @@ -0,0 +1,20 @@ +// 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"); +} diff --git a/src/test/ui/default-associated-types.rs b/src/test/ui/default-associated-types.rs new file mode 100644 index 00000000000..aae70bffa38 --- /dev/null +++ b/src/test/ui/default-associated-types.rs @@ -0,0 +1,23 @@ +// run-pass + +#![feature(associated_type_defaults)] + +trait Foo { + type Out: Default + ToString = T; +} + +impl Foo for () { +} + +impl Foo for () { + type Out = bool; +} + +fn main() { + assert_eq!( + <() as Foo>::Out::default().to_string(), + "0"); + assert_eq!( + <() as Foo>::Out::default().to_string(), + "false"); +} diff --git a/src/test/ui/default-method-parsing.rs b/src/test/ui/default-method-parsing.rs new file mode 100644 index 00000000000..9ffb8d94a59 --- /dev/null +++ b/src/test/ui/default-method-parsing.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + fn m(&self, _:isize) { } +} + +pub fn main() { } diff --git a/src/test/ui/default-method-simple.rs b/src/test/ui/default-method-simple.rs new file mode 100644 index 00000000000..6f7ae6a3e0b --- /dev/null +++ b/src/test/ui/default-method-simple.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/defaults-well-formedness.rs b/src/test/ui/defaults-well-formedness.rs new file mode 100644 index 00000000000..3275890616b --- /dev/null +++ b/src/test/ui/defaults-well-formedness.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/deprecation-in-force-unstable.rs b/src/test/ui/deprecation-in-force-unstable.rs new file mode 100644 index 00000000000..4df9b802d45 --- /dev/null +++ b/src/test/ui/deprecation-in-force-unstable.rs @@ -0,0 +1,5 @@ +// run-pass +// compile-flags:-Zforce-unstable-if-unmarked + +#[deprecated] // should work even with -Zforce-unstable-if-unmarked +fn main() { } diff --git a/src/test/ui/deref-lval.rs b/src/test/ui/deref-lval.rs new file mode 100644 index 00000000000..f57872f80e0 --- /dev/null +++ b/src/test/ui/deref-lval.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(box_syntax)] + +use std::cell::Cell; + +pub fn main() { + let x: Box<_> = box Cell::new(5); + x.set(1000); + println!("{}", x.get()); +} diff --git a/src/test/ui/deref-mut-on-ref.rs b/src/test/ui/deref-mut-on-ref.rs new file mode 100644 index 00000000000..a6df5495a27 --- /dev/null +++ b/src/test/ui/deref-mut-on-ref.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/deref-on-ref.rs b/src/test/ui/deref-on-ref.rs new file mode 100644 index 00000000000..973e61c9d59 --- /dev/null +++ b/src/test/ui/deref-on-ref.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/deref-rc.rs b/src/test/ui/deref-rc.rs new file mode 100644 index 00000000000..9b4c63b1925 --- /dev/null +++ b/src/test/ui/deref-rc.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/deref.rs b/src/test/ui/deref.rs new file mode 100644 index 00000000000..cad4ede06a5 --- /dev/null +++ b/src/test/ui/deref.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let x: Box = box 10; + let _y: isize = *x; +} diff --git a/src/test/ui/deriving/auxiliary/derive-no-std.rs b/src/test/ui/deriving/auxiliary/derive-no-std.rs new file mode 100644 index 00000000000..3893dc1be07 --- /dev/null +++ b/src/test/ui/deriving/auxiliary/derive-no-std.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/deriving/derive-no-std.rs b/src/test/ui/deriving/derive-no-std.rs new file mode 100644 index 00000000000..74c73b99cb9 --- /dev/null +++ b/src/test/ui/deriving/derive-no-std.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/deriving/derive-partialord-correctness.rs b/src/test/ui/deriving/derive-partialord-correctness.rs new file mode 100644 index 00000000000..36763eda169 --- /dev/null +++ b/src/test/ui/deriving/derive-partialord-correctness.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/deriving/deriving-associated-types.rs b/src/test/ui/deriving/deriving-associated-types.rs new file mode 100644 index 00000000000..4b1cbe80c50 --- /dev/null +++ b/src/test/ui/deriving/deriving-associated-types.rs @@ -0,0 +1,199 @@ +// run-pass +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/src/test/ui/deriving/deriving-bounds.rs b/src/test/ui/deriving/deriving-bounds.rs new file mode 100644 index 00000000000..f0b921d0e7c --- /dev/null +++ b/src/test/ui/deriving/deriving-bounds.rs @@ -0,0 +1,5 @@ +// run-pass +#[derive(Copy, Clone)] +struct Test; + +pub fn main() {} diff --git a/src/test/ui/deriving/deriving-clone-array.rs b/src/test/ui/deriving/deriving-clone-array.rs new file mode 100644 index 00000000000..4569749df42 --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-array.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// test for issue #30244 + +#[derive(Copy, Clone)] +struct Array { + arr: [[u8; 256]; 4] +} + +pub fn main() {} diff --git a/src/test/ui/deriving/deriving-clone-enum.rs b/src/test/ui/deriving/deriving-clone-enum.rs new file mode 100644 index 00000000000..09e74974072 --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-enum.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/deriving/deriving-clone-generic-enum.rs b/src/test/ui/deriving/deriving-clone-generic-enum.rs new file mode 100644 index 00000000000..a344d7fc43a --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-generic-enum.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/deriving/deriving-clone-generic-struct.rs b/src/test/ui/deriving/deriving-clone-generic-struct.rs new file mode 100644 index 00000000000..f6e105555fd --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-generic-struct.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs new file mode 100644 index 00000000000..8b9840de172 --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S(T, ()); + +pub fn main() { + let _ = S(1, ()).clone(); +} diff --git a/src/test/ui/deriving/deriving-clone-struct.rs b/src/test/ui/deriving/deriving-clone-struct.rs new file mode 100644 index 00000000000..7b0a1d20260 --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-struct.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/deriving/deriving-clone-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-tuple-struct.rs new file mode 100644 index 00000000000..166f1be55e0 --- /dev/null +++ b/src/test/ui/deriving/deriving-clone-tuple-struct.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S((), ()); + +pub fn main() {} diff --git a/src/test/ui/deriving/deriving-cmp-generic-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-enum.rs new file mode 100644 index 00000000000..88da4bd066c --- /dev/null +++ b/src/test/ui/deriving/deriving-cmp-generic-enum.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs new file mode 100644 index 00000000000..eeaf2ff7efa --- /dev/null +++ b/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/deriving/deriving-cmp-generic-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-struct.rs new file mode 100644 index 00000000000..538caf439c7 --- /dev/null +++ b/src/test/ui/deriving/deriving-cmp-generic-struct.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs new file mode 100644 index 00000000000..79f58d4565c --- /dev/null +++ b/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/deriving/deriving-cmp-shortcircuit.rs b/src/test/ui/deriving/deriving-cmp-shortcircuit.rs new file mode 100644 index 00000000000..140373e9526 --- /dev/null +++ b/src/test/ui/deriving/deriving-cmp-shortcircuit.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/deriving/deriving-copyclone.rs b/src/test/ui/deriving/deriving-copyclone.rs new file mode 100644 index 00000000000..78d74a11ffc --- /dev/null +++ b/src/test/ui/deriving/deriving-copyclone.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/deriving/deriving-default-box.rs b/src/test/ui/deriving/deriving-default-box.rs new file mode 100644 index 00000000000..237dbfaa056 --- /dev/null +++ b/src/test/ui/deriving/deriving-default-box.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/deriving/deriving-enum-single-variant.rs b/src/test/ui/deriving/deriving-enum-single-variant.rs new file mode 100644 index 00000000000..1c5979c0747 --- /dev/null +++ b/src/test/ui/deriving/deriving-enum-single-variant.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs b/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs new file mode 100644 index 00000000000..5b4b0983623 --- /dev/null +++ b/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/deriving/deriving-hash.rs b/src/test/ui/deriving/deriving-hash.rs new file mode 100644 index 00000000000..68c68c235ef --- /dev/null +++ b/src/test/ui/deriving/deriving-hash.rs @@ -0,0 +1,76 @@ +// 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_with_keys(0, 0); + 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/src/test/ui/deriving/deriving-in-fn.rs b/src/test/ui/deriving/deriving-in-fn.rs new file mode 100644 index 00000000000..8931e94a4f8 --- /dev/null +++ b/src/test/ui/deriving/deriving-in-fn.rs @@ -0,0 +1,10 @@ +// run-pass +pub fn main() { + #[derive(Debug)] + struct Foo { + foo: isize, + } + + let f = Foo { foo: 10 }; + format!("{:?}", f); +} diff --git a/src/test/ui/deriving/deriving-in-macro.rs b/src/test/ui/deriving/deriving-in-macro.rs new file mode 100644 index 00000000000..46e8e37838d --- /dev/null +++ b/src/test/ui/deriving/deriving-in-macro.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/deriving/deriving-meta-multiple.rs b/src/test/ui/deriving/deriving-meta-multiple.rs new file mode 100644 index 00000000000..ad255be8dab --- /dev/null +++ b/src/test/ui/deriving/deriving-meta-multiple.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/deriving/deriving-meta.rs b/src/test/ui/deriving/deriving-meta.rs new file mode 100644 index 00000000000..f2ff4f53557 --- /dev/null +++ b/src/test/ui/deriving/deriving-meta.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs b/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs new file mode 100644 index 00000000000..e01b5a26fc7 --- /dev/null +++ b/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/deriving/deriving-show-2.rs b/src/test/ui/deriving/deriving-show-2.rs new file mode 100644 index 00000000000..13d124ed4c3 --- /dev/null +++ b/src/test/ui/deriving/deriving-show-2.rs @@ -0,0 +1,54 @@ +// 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/src/test/ui/deriving/deriving-show.rs b/src/test/ui/deriving/deriving-show.rs new file mode 100644 index 00000000000..eb3a8948fc8 --- /dev/null +++ b/src/test/ui/deriving/deriving-show.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/deriving/deriving-via-extension-c-enum.rs b/src/test/ui/deriving/deriving-via-extension-c-enum.rs new file mode 100644 index 00000000000..7fa1a69d7e0 --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-c-enum.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/deriving/deriving-via-extension-enum.rs b/src/test/ui/deriving/deriving-via-extension-enum.rs new file mode 100644 index 00000000000..6b58fd96622 --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-enum.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/deriving/deriving-via-extension-hash-enum.rs b/src/test/ui/deriving/deriving-via-extension-hash-enum.rs new file mode 100644 index 00000000000..2d1ca05f4fc --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-hash-enum.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/deriving/deriving-via-extension-hash-struct.rs b/src/test/ui/deriving/deriving-via-extension-hash-struct.rs new file mode 100644 index 00000000000..c4037dc2714 --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-hash-struct.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/deriving/deriving-via-extension-struct-empty.rs b/src/test/ui/deriving/deriving-via-extension-struct-empty.rs new file mode 100644 index 00000000000..9fb250e8470 --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-struct-empty.rs @@ -0,0 +1,8 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Foo; + +pub fn main() { + assert_eq!(Foo, Foo); + assert!(!(Foo != Foo)); +} diff --git a/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs b/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs new file mode 100644 index 00000000000..b6e6f136c75 --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs b/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs new file mode 100644 index 00000000000..e84906c96bb --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/deriving/deriving-via-extension-struct.rs b/src/test/ui/deriving/deriving-via-extension-struct.rs new file mode 100644 index 00000000000..f4d8b16a02f --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-struct.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/deriving/deriving-via-extension-type-params.rs b/src/test/ui/deriving/deriving-via-extension-type-params.rs new file mode 100644 index 00000000000..a5dec8ee1ab --- /dev/null +++ b/src/test/ui/deriving/deriving-via-extension-type-params.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/deriving/deriving-with-repr-packed.rs b/src/test/ui/deriving/deriving-with-repr-packed.rs new file mode 100644 index 00000000000..8ce444be13f --- /dev/null +++ b/src/test/ui/deriving/deriving-with-repr-packed.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/dispatch_from_dyn_zst.rs b/src/test/ui/dispatch_from_dyn_zst.rs new file mode 100644 index 00000000000..764f58ce9e8 --- /dev/null +++ b/src/test/ui/dispatch_from_dyn_zst.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/diverging-fallback-control-flow.rs b/src/test/ui/diverging-fallback-control-flow.rs new file mode 100644 index 00000000000..0f0f787b407 --- /dev/null +++ b/src/test/ui/diverging-fallback-control-flow.rs @@ -0,0 +1,101 @@ +// 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)] + +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/src/test/ui/diverging-fallback-method-chain.rs b/src/test/ui/diverging-fallback-method-chain.rs new file mode 100644 index 00000000000..ba9f05c64e4 --- /dev/null +++ b/src/test/ui/diverging-fallback-method-chain.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/diverging-fallback-option.rs b/src/test/ui/diverging-fallback-option.rs new file mode 100644 index 00000000000..46bdfc96dbe --- /dev/null +++ b/src/test/ui/diverging-fallback-option.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/double-ref.rs b/src/test/ui/double-ref.rs new file mode 100644 index 00000000000..e68b8683376 --- /dev/null +++ b/src/test/ui/double-ref.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs b/src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs new file mode 100644 index 00000000000..270d5de7ac8 --- /dev/null +++ b/src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs @@ -0,0 +1,50 @@ +#![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/src/test/ui/drop/drop-on-empty-block-exit.rs b/src/test/ui/drop/drop-on-empty-block-exit.rs new file mode 100644 index 00000000000..1747bf029aa --- /dev/null +++ b/src/test/ui/drop/drop-on-empty-block-exit.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/drop/drop-on-ret.rs b/src/test/ui/drop/drop-on-ret.rs new file mode 100644 index 00000000000..290e274f305 --- /dev/null +++ b/src/test/ui/drop/drop-on-ret.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/drop/drop-struct-as-object.rs b/src/test/ui/drop/drop-struct-as-object.rs new file mode 100644 index 00000000000..1bc3b4c157c --- /dev/null +++ b/src/test/ui/drop/drop-struct-as-object.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/drop/drop-trait-enum.rs b/src/test/ui/drop/drop-trait-enum.rs new file mode 100644 index 00000000000..aec46575f97 --- /dev/null +++ b/src/test/ui/drop/drop-trait-enum.rs @@ -0,0 +1,95 @@ +// 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/src/test/ui/drop/drop-trait-generic.rs b/src/test/ui/drop/drop-trait-generic.rs new file mode 100644 index 00000000000..cdefb680c75 --- /dev/null +++ b/src/test/ui/drop/drop-trait-generic.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/drop/drop-trait.rs b/src/test/ui/drop/drop-trait.rs new file mode 100644 index 00000000000..d93f7718091 --- /dev/null +++ b/src/test/ui/drop/drop-trait.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/drop/drop-uninhabited-enum.rs b/src/test/ui/drop/drop-uninhabited-enum.rs new file mode 100644 index 00000000000..b3566f68533 --- /dev/null +++ b/src/test/ui/drop/drop-uninhabited-enum.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/drop/drop-with-type-ascription-1.rs b/src/test/ui/drop/drop-with-type-ascription-1.rs new file mode 100644 index 00000000000..e5a1a48df56 --- /dev/null +++ b/src/test/ui/drop/drop-with-type-ascription-1.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/drop/drop-with-type-ascription-2.rs b/src/test/ui/drop/drop-with-type-ascription-2.rs new file mode 100644 index 00000000000..fb70ad48e88 --- /dev/null +++ b/src/test/ui/drop/drop-with-type-ascription-2.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/drop/dropck-eyepatch-extern-crate.rs b/src/test/ui/drop/dropck-eyepatch-extern-crate.rs new file mode 100644 index 00000000000..fecfd5edffb --- /dev/null +++ b/src/test/ui/drop/dropck-eyepatch-extern-crate.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/drop/dropck-eyepatch-reorder.rs b/src/test/ui/drop/dropck-eyepatch-reorder.rs new file mode 100644 index 00000000000..b4605878a54 --- /dev/null +++ b/src/test/ui/drop/dropck-eyepatch-reorder.rs @@ -0,0 +1,79 @@ +// 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/src/test/ui/drop/dropck-eyepatch.rs b/src/test/ui/drop/dropck-eyepatch.rs new file mode 100644 index 00000000000..9255391e412 --- /dev/null +++ b/src/test/ui/drop/dropck-eyepatch.rs @@ -0,0 +1,102 @@ +// 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/src/test/ui/drop/dropck_legal_cycles.rs b/src/test/ui/drop/dropck_legal_cycles.rs new file mode 100644 index 00000000000..a4f4c2666ac --- /dev/null +++ b/src/test/ui/drop/dropck_legal_cycles.rs @@ -0,0 +1,1183 @@ +// 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/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs new file mode 100644 index 00000000000..9226145d935 --- /dev/null +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -0,0 +1,328 @@ +// 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_assignments)] +#![allow(unused_variables)] +#![feature(slice_patterns)] +#![feature(async_await)] + +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; +} + +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)); +} diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs new file mode 100644 index 00000000000..eb1a3f3a9f9 --- /dev/null +++ b/src/test/ui/drop/dynamic-drop.rs @@ -0,0 +1,436 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait, untagged_unions)] +#![feature(slice_patterns)] + +use std::cell::{Cell, RefCell}; +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; +} + +#[allow(unions_with_drop_fields)] +union Boxy { + a: T, + b: T, +} + +fn union1(a: &Allocator) { + unsafe { + let mut u = Boxy { a: a.alloc() }; + u.b = a.alloc(); + drop(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 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| { + 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_nopanic(|a| union1(a)); +} diff --git a/src/test/ui/drop/no-drop-flag-size.rs b/src/test/ui/drop/no-drop-flag-size.rs new file mode 100644 index 00000000000..103e70ef6ee --- /dev/null +++ b/src/test/ui/drop/no-drop-flag-size.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/drop/nondrop-cycle.rs b/src/test/ui/drop/nondrop-cycle.rs new file mode 100644 index 00000000000..29070f917e4 --- /dev/null +++ b/src/test/ui/drop/nondrop-cycle.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/dupe-first-attr.rc b/src/test/ui/dupe-first-attr.rc new file mode 100644 index 00000000000..8b7025b7be7 --- /dev/null +++ b/src/test/ui/dupe-first-attr.rc @@ -0,0 +1,24 @@ +// Regression test for a problem with the first mod attribute +// being applied to every mod + +// pretty-expanded FIXME #23616 + +#[cfg(target_os = "linux")] +mod hello; + +#[cfg(target_os = "macos")] +mod hello; + +#[cfg(target_os = "windows")] +mod hello; + +#[cfg(target_os = "freebsd")] +mod hello; + +#[cfg(target_os = "dragonfly")] +mod hello; + +#[cfg(target_os = "android")] +mod hello; + +pub fn main() { } diff --git a/src/test/ui/duplicated-external-mods.rs b/src/test/ui/duplicated-external-mods.rs new file mode 100644 index 00000000000..05a279a3014 --- /dev/null +++ b/src/test/ui/duplicated-external-mods.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/dynamically-sized-types/dst-coerce-custom.rs b/src/test/ui/dynamically-sized-types/dst-coerce-custom.rs new file mode 100644 index 00000000000..24d83eb5343 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-coerce-custom.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/dynamically-sized-types/dst-coerce-rc.rs b/src/test/ui/dynamically-sized-types/dst-coerce-rc.rs new file mode 100644 index 00000000000..683fa6850fd --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-coerce-rc.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/dynamically-sized-types/dst-coercions.rs b/src/test/ui/dynamically-sized-types/dst-coercions.rs new file mode 100644 index 00000000000..66688e93fb8 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-coercions.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/dynamically-sized-types/dst-deref-mut.rs b/src/test/ui/dynamically-sized-types/dst-deref-mut.rs new file mode 100644 index 00000000000..1d62f42bd4a --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-deref-mut.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/dynamically-sized-types/dst-deref.rs b/src/test/ui/dynamically-sized-types/dst-deref.rs new file mode 100644 index 00000000000..0a350bac14a --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-deref.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/dynamically-sized-types/dst-field-align.rs b/src/test/ui/dynamically-sized-types/dst-field-align.rs new file mode 100644 index 00000000000..6c338e99912 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-field-align.rs @@ -0,0 +1,67 @@ +// 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/src/test/ui/dynamically-sized-types/dst-index.rs b/src/test/ui/dynamically-sized-types/dst-index.rs new file mode 100644 index 00000000000..980d99a6d6c --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-index.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs b/src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs new file mode 100644 index 00000000000..0a6c49111fe --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/dynamically-sized-types/dst-raw.rs b/src/test/ui/dynamically-sized-types/dst-raw.rs new file mode 100644 index 00000000000..0893b02e74e --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-raw.rs @@ -0,0 +1,138 @@ +// 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/src/test/ui/dynamically-sized-types/dst-struct-sole.rs b/src/test/ui/dynamically-sized-types/dst-struct-sole.rs new file mode 100644 index 00000000000..6ca07fcf8da --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-struct-sole.rs @@ -0,0 +1,76 @@ +// 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/src/test/ui/dynamically-sized-types/dst-struct.rs b/src/test/ui/dynamically-sized-types/dst-struct.rs new file mode 100644 index 00000000000..25ec07b88a6 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-struct.rs @@ -0,0 +1,122 @@ +// 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/src/test/ui/dynamically-sized-types/dst-trait-tuple.rs b/src/test/ui/dynamically-sized-types/dst-trait-tuple.rs new file mode 100644 index 00000000000..70bcc3de07d --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-trait-tuple.rs @@ -0,0 +1,103 @@ +// 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/src/test/ui/dynamically-sized-types/dst-trait.rs b/src/test/ui/dynamically-sized-types/dst-trait.rs new file mode 100644 index 00000000000..ec6bc72192d --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-trait.rs @@ -0,0 +1,105 @@ +// 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/src/test/ui/dynamically-sized-types/dst-tuple-sole.rs b/src/test/ui/dynamically-sized-types/dst-tuple-sole.rs new file mode 100644 index 00000000000..606689da0c2 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-tuple-sole.rs @@ -0,0 +1,79 @@ +// 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/src/test/ui/dynamically-sized-types/dst-tuple.rs b/src/test/ui/dynamically-sized-types/dst-tuple.rs new file mode 100644 index 00000000000..f70a45a1b35 --- /dev/null +++ b/src/test/ui/dynamically-sized-types/dst-tuple.rs @@ -0,0 +1,120 @@ +// 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/src/test/ui/early-ret-binop-add.rs b/src/test/ui/early-ret-binop-add.rs new file mode 100644 index 00000000000..2b5df52a51c --- /dev/null +++ b/src/test/ui/early-ret-binop-add.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/early-vtbl-resolution.rs b/src/test/ui/early-vtbl-resolution.rs new file mode 100644 index 00000000000..f4b69c14095 --- /dev/null +++ b/src/test/ui/early-vtbl-resolution.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/edition-keywords-2015-2015.rs b/src/test/ui/edition-keywords-2015-2015.rs new file mode 100644 index 00000000000..943d203b806 --- /dev/null +++ b/src/test/ui/edition-keywords-2015-2015.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/edition-keywords-2015-2018.rs b/src/test/ui/edition-keywords-2015-2018.rs new file mode 100644 index 00000000000..8c3397c951d --- /dev/null +++ b/src/test/ui/edition-keywords-2015-2018.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/edition-keywords-2018-2015.rs b/src/test/ui/edition-keywords-2018-2015.rs new file mode 100644 index 00000000000..2cb2dfb18a0 --- /dev/null +++ b/src/test/ui/edition-keywords-2018-2015.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/edition-keywords-2018-2018.rs b/src/test/ui/edition-keywords-2018-2018.rs new file mode 100644 index 00000000000..5043440aa16 --- /dev/null +++ b/src/test/ui/edition-keywords-2018-2018.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/else-if.rs b/src/test/ui/else-if.rs new file mode 100644 index 00000000000..77d8d1abfaf --- /dev/null +++ b/src/test/ui/else-if.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/empty-allocation-non-null.rs b/src/test/ui/empty-allocation-non-null.rs new file mode 100644 index 00000000000..925bddd5edd --- /dev/null +++ b/src/test/ui/empty-allocation-non-null.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/empty-allocation-rvalue-non-null.rs b/src/test/ui/empty-allocation-rvalue-non-null.rs new file mode 100644 index 00000000000..2f5a5c4bbc6 --- /dev/null +++ b/src/test/ui/empty-allocation-rvalue-non-null.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = *Box::new(()); +} diff --git a/src/test/ui/empty-type-parameter-list.rs b/src/test/ui/empty-type-parameter-list.rs new file mode 100644 index 00000000000..e168cd03b27 --- /dev/null +++ b/src/test/ui/empty-type-parameter-list.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/empty_global_asm.rs b/src/test/ui/empty_global_asm.rs new file mode 100644 index 00000000000..efbe2b2eb67 --- /dev/null +++ b/src/test/ui/empty_global_asm.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/env-args-reverse-iterator.rs b/src/test/ui/env-args-reverse-iterator.rs new file mode 100644 index 00000000000..0ffd74f87ab --- /dev/null +++ b/src/test/ui/env-args-reverse-iterator.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/env-funky-keys.rs b/src/test/ui/env-funky-keys.rs new file mode 100644 index 00000000000..4faceb53266 --- /dev/null +++ b/src/test/ui/env-funky-keys.rs @@ -0,0 +1,42 @@ +// 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 +// 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/src/test/ui/env-home-dir.rs b/src/test/ui/env-home-dir.rs new file mode 100644 index 00000000000..a75be48fd55 --- /dev/null +++ b/src/test/ui/env-home-dir.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/env-null-vars.rs b/src/test/ui/env-null-vars.rs new file mode 100644 index 00000000000..10582a8a514 --- /dev/null +++ b/src/test/ui/env-null-vars.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/env-vars.rs b/src/test/ui/env-vars.rs new file mode 100644 index 00000000000..2ea906788e8 --- /dev/null +++ b/src/test/ui/env-vars.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/epoch-gate-feature.rs b/src/test/ui/epoch-gate-feature.rs new file mode 100644 index 00000000000..5f7feb5347b --- /dev/null +++ b/src/test/ui/epoch-gate-feature.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/eq-multidispatch.rs b/src/test/ui/eq-multidispatch.rs new file mode 100644 index 00000000000..69d83f496b3 --- /dev/null +++ b/src/test/ui/eq-multidispatch.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/estr-uniq.rs b/src/test/ui/estr-uniq.rs new file mode 100644 index 00000000000..1d0a4273953 --- /dev/null +++ b/src/test/ui/estr-uniq.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/exec-env.rs b/src/test/ui/exec-env.rs new file mode 100644 index 00000000000..230fac10d33 --- /dev/null +++ b/src/test/ui/exec-env.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/existential_type.rs b/src/test/ui/existential_type.rs new file mode 100644 index 00000000000..c2cf0eeed3d --- /dev/null +++ b/src/test/ui/existential_type.rs @@ -0,0 +1,89 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![feature(existential_type)] + +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 +existential type Foo: std::fmt::Display; + +fn foo() -> Foo { + "foo" +} + +// two definitions +existential type Bar: std::fmt::Display; + +fn bar1() -> Bar { + "bar1" +} + +fn bar2() -> Bar { + "bar2" +} + +// definition in submodule +existential type Boo: std::fmt::Display; + +mod boo { + pub fn boo() -> super::Boo { + "boo" + } +} + +existential type MyIter: 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! +existential type MyOtherIter: Iterator; + +fn my_other_iter(u: U) -> MyOtherIter { + std::iter::once(u) +} + +trait Trait {} +existential type GenericBound<'a, T: Trait>: Sized + 'a; + +fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { + t +} + +mod pass_through { + pub existential type Passthrough: Sized + 'static; + + fn define_passthrough(t: T) -> Passthrough { + t + } +} + +fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { + x +} diff --git a/src/test/ui/explicit-i-suffix.rs b/src/test/ui/explicit-i-suffix.rs new file mode 100644 index 00000000000..40c7e475104 --- /dev/null +++ b/src/test/ui/explicit-i-suffix.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/export-glob-imports-target.rs b/src/test/ui/export-glob-imports-target.rs new file mode 100644 index 00000000000..4df807ea4c9 --- /dev/null +++ b/src/test/ui/export-glob-imports-target.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/export-multi.rs b/src/test/ui/export-multi.rs new file mode 100644 index 00000000000..02bdbe8afff --- /dev/null +++ b/src/test/ui/export-multi.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/export-non-interference2.rs b/src/test/ui/export-non-interference2.rs new file mode 100644 index 00000000000..6d18b03891a --- /dev/null +++ b/src/test/ui/export-non-interference2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/export-non-interference3.rs b/src/test/ui/export-non-interference3.rs new file mode 100644 index 00000000000..0d6b6369f94 --- /dev/null +++ b/src/test/ui/export-non-interference3.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/expr-block-fn.rs b/src/test/ui/expr-block-fn.rs new file mode 100644 index 00000000000..1cac2cac0ac --- /dev/null +++ b/src/test/ui/expr-block-fn.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/expr-block-generic-unique1.rs b/src/test/ui/expr-block-generic-unique1.rs new file mode 100644 index 00000000000..c14191f2ffc --- /dev/null +++ b/src/test/ui/expr-block-generic-unique1.rs @@ -0,0 +1,19 @@ +// run-pass + +#![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/src/test/ui/expr-block-generic-unique2.rs b/src/test/ui/expr-block-generic-unique2.rs new file mode 100644 index 00000000000..90ebc02931a --- /dev/null +++ b/src/test/ui/expr-block-generic-unique2.rs @@ -0,0 +1,15 @@ +// run-pass + +#![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/src/test/ui/expr-block-generic.rs b/src/test/ui/expr-block-generic.rs new file mode 100644 index 00000000000..ec93f59722d --- /dev/null +++ b/src/test/ui/expr-block-generic.rs @@ -0,0 +1,26 @@ +// run-pass + +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/src/test/ui/expr-block-slot.rs b/src/test/ui/expr-block-slot.rs new file mode 100644 index 00000000000..54bcbb328b0 --- /dev/null +++ b/src/test/ui/expr-block-slot.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/expr-block-unique.rs b/src/test/ui/expr-block-unique.rs new file mode 100644 index 00000000000..fe1a7d9f1fb --- /dev/null +++ b/src/test/ui/expr-block-unique.rs @@ -0,0 +1,5 @@ +// run-pass + +#![feature(box_syntax)] + +pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); } diff --git a/src/test/ui/expr-block.rs b/src/test/ui/expr-block.rs new file mode 100644 index 00000000000..549ccf9774f --- /dev/null +++ b/src/test/ui/expr-block.rs @@ -0,0 +1,21 @@ +// run-pass + +#![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/src/test/ui/expr-copy.rs b/src/test/ui/expr-copy.rs new file mode 100644 index 00000000000..1c6ae03810f --- /dev/null +++ b/src/test/ui/expr-copy.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/expr-empty-ret.rs b/src/test/ui/expr-empty-ret.rs new file mode 100644 index 00000000000..ce8ffaf94d0 --- /dev/null +++ b/src/test/ui/expr-empty-ret.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/expr-fn.rs b/src/test/ui/expr-fn.rs new file mode 100644 index 00000000000..af809f563fc --- /dev/null +++ b/src/test/ui/expr-fn.rs @@ -0,0 +1,61 @@ +// run-pass + +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/src/test/ui/expr-if-generic.rs b/src/test/ui/expr-if-generic.rs new file mode 100644 index 00000000000..32ed6d9bee0 --- /dev/null +++ b/src/test/ui/expr-if-generic.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/expr-if-panic-all.rs b/src/test/ui/expr-if-panic-all.rs new file mode 100644 index 00000000000..f915a7d9da0 --- /dev/null +++ b/src/test/ui/expr-if-panic-all.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/expr-if-panic.rs b/src/test/ui/expr-if-panic.rs new file mode 100644 index 00000000000..6069cd835e1 --- /dev/null +++ b/src/test/ui/expr-if-panic.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/expr-if-unique.rs b/src/test/ui/expr-if-unique.rs new file mode 100644 index 00000000000..509d069d40f --- /dev/null +++ b/src/test/ui/expr-if-unique.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/expr-if.rs b/src/test/ui/expr-if.rs new file mode 100644 index 00000000000..2b8474ff453 --- /dev/null +++ b/src/test/ui/expr-if.rs @@ -0,0 +1,52 @@ +// 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/src/test/ui/expr-scope.rs b/src/test/ui/expr-scope.rs new file mode 100644 index 00000000000..9976b6814c0 --- /dev/null +++ b/src/test/ui/expr-scope.rs @@ -0,0 +1,7 @@ +// run-pass +// Regression test for issue #762 + +// pretty-expanded FIXME #23616 + +pub fn f() { } +pub fn main() { return ::f(); } diff --git a/src/test/ui/ext-expand-inner-exprs.rs b/src/test/ui/ext-expand-inner-exprs.rs new file mode 100644 index 00000000000..5bbdf5ec956 --- /dev/null +++ b/src/test/ui/ext-expand-inner-exprs.rs @@ -0,0 +1,7 @@ +// run-pass + +static FOO : &'static str = concat!(concat!("hel", "lo"), "world"); + +pub fn main() { + assert_eq!(FOO, "helloworld"); +} diff --git a/src/test/ui/extend-for-unit.rs b/src/test/ui/extend-for-unit.rs new file mode 100644 index 00000000000..01d743f70bc --- /dev/null +++ b/src/test/ui/extend-for-unit.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/exterior.rs b/src/test/ui/exterior.rs new file mode 100644 index 00000000000..6f2c37926be --- /dev/null +++ b/src/test/ui/exterior.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(dead_code)] + + +use std::cell::Cell; + +#[derive(Copy, Clone)] +struct Point {x: isize, y: isize, z: isize} + +fn f(p: &Cell) { + assert_eq!(p.get().z, 12); + p.set(Point {x: 10, y: 11, z: 13}); + assert_eq!(p.get().z, 13); +} + +pub fn main() { + let a: Point = Point {x: 10, y: 11, z: 12}; + let b: &Cell = &Cell::new(a); + assert_eq!(b.get().z, 12); + f(b); + assert_eq!(a.z, 12); + assert_eq!(b.get().z, 13); +} diff --git a/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs b/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs new file mode 100644 index 00000000000..d4568d38e25 --- /dev/null +++ b/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs @@ -0,0 +1,31 @@ +#![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/src/test/ui/extern/auxiliary/extern-take-value.rs b/src/test/ui/extern/auxiliary/extern-take-value.rs new file mode 100644 index 00000000000..869e794cc8a --- /dev/null +++ b/src/test/ui/extern/auxiliary/extern-take-value.rs @@ -0,0 +1,5 @@ +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/src/test/ui/extern/auxiliary/extern_calling_convention.rs b/src/test/ui/extern/auxiliary/extern_calling_convention.rs new file mode 100644 index 00000000000..968b1a25510 --- /dev/null +++ b/src/test/ui/extern/auxiliary/extern_calling_convention.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs b/src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs new file mode 100644 index 00000000000..7357f59700e --- /dev/null +++ b/src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs @@ -0,0 +1,5 @@ +#![crate_type="lib"] + +pub mod extern_mod_ordering_lib { + pub fn f() {} +} diff --git a/src/test/ui/extern/auxiliary/fat_drop.rs b/src/test/ui/extern/auxiliary/fat_drop.rs new file mode 100644 index 00000000000..768d29876b9 --- /dev/null +++ b/src/test/ui/extern/auxiliary/fat_drop.rs @@ -0,0 +1,13 @@ +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/src/test/ui/extern/extern-1.rs b/src/test/ui/extern/extern-1.rs new file mode 100644 index 00000000000..eb9aabc87bc --- /dev/null +++ b/src/test/ui/extern/extern-1.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern fn f() { +} + +pub fn main() { +} diff --git a/src/test/ui/extern/extern-call-deep.rs b/src/test/ui/extern/extern-call-deep.rs new file mode 100644 index 00000000000..81f884dada9 --- /dev/null +++ b/src/test/ui/extern/extern-call-deep.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/extern/extern-call-deep2.rs b/src/test/ui/extern/extern-call-deep2.rs new file mode 100644 index 00000000000..b31489b1e10 --- /dev/null +++ b/src/test/ui/extern/extern-call-deep2.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/extern/extern-call-direct.rs b/src/test/ui/extern/extern-call-direct.rs new file mode 100644 index 00000000000..72041764215 --- /dev/null +++ b/src/test/ui/extern/extern-call-direct.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/extern/extern-call-indirect.rs b/src/test/ui/extern/extern-call-indirect.rs new file mode 100644 index 00000000000..158b54e4b8c --- /dev/null +++ b/src/test/ui/extern/extern-call-indirect.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/extern/extern-call-scrub.rs b/src/test/ui/extern/extern-call-scrub.rs new file mode 100644 index 00000000000..a7b1065c9e1 --- /dev/null +++ b/src/test/ui/extern/extern-call-scrub.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/extern/extern-calling-convention-test.rs b/src/test/ui/extern/extern-calling-convention-test.rs new file mode 100644 index 00000000000..7231a7cde85 --- /dev/null +++ b/src/test/ui/extern/extern-calling-convention-test.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/extern/extern-compare-with-return-type.rs b/src/test/ui/extern/extern-compare-with-return-type.rs new file mode 100644 index 00000000000..6c9ed3760f6 --- /dev/null +++ b/src/test/ui/extern/extern-compare-with-return-type.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/extern/extern-crosscrate.rs b/src/test/ui/extern/extern-crosscrate.rs new file mode 100644 index 00000000000..123ce20ca26 --- /dev/null +++ b/src/test/ui/extern/extern-crosscrate.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/extern/extern-foreign-crate.rs b/src/test/ui/extern/extern-foreign-crate.rs new file mode 100644 index 00000000000..7f774c44277 --- /dev/null +++ b/src/test/ui/extern/extern-foreign-crate.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +extern crate std as mystd; + +pub fn main() {} diff --git a/src/test/ui/extern/extern-methods.rs b/src/test/ui/extern/extern-methods.rs new file mode 100644 index 00000000000..b142ec59e88 --- /dev/null +++ b/src/test/ui/extern/extern-methods.rs @@ -0,0 +1,30 @@ +// run-pass +// ignore-arm +// ignore-aarch64 + +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/src/test/ui/extern/extern-mod-abi.rs b/src/test/ui/extern/extern-mod-abi.rs new file mode 100644 index 00000000000..c543394cca0 --- /dev/null +++ b/src/test/ui/extern/extern-mod-abi.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern "C" { + fn pow(x: f64, y: f64) -> f64; +} + +pub fn main() {} diff --git a/src/test/ui/extern/extern-mod-ordering-exe.rs b/src/test/ui/extern/extern-mod-ordering-exe.rs new file mode 100644 index 00000000000..d7cc4dffb44 --- /dev/null +++ b/src/test/ui/extern/extern-mod-ordering-exe.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/extern/extern-pass-TwoU16s.rs b/src/test/ui/extern/extern-pass-TwoU16s.rs new file mode 100644 index 00000000000..285bce2e19c --- /dev/null +++ b/src/test/ui/extern/extern-pass-TwoU16s.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/extern/extern-pass-TwoU32s.rs b/src/test/ui/extern/extern-pass-TwoU32s.rs new file mode 100644 index 00000000000..fb18aa8d22f --- /dev/null +++ b/src/test/ui/extern/extern-pass-TwoU32s.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/extern/extern-pass-TwoU64s.rs b/src/test/ui/extern/extern-pass-TwoU64s.rs new file mode 100644 index 00000000000..419648263aa --- /dev/null +++ b/src/test/ui/extern/extern-pass-TwoU64s.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/extern/extern-pass-TwoU8s.rs b/src/test/ui/extern/extern-pass-TwoU8s.rs new file mode 100644 index 00000000000..53a6a0f29f8 --- /dev/null +++ b/src/test/ui/extern/extern-pass-TwoU8s.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/extern/extern-pass-char.rs b/src/test/ui/extern/extern-pass-char.rs new file mode 100644 index 00000000000..22f841b4552 --- /dev/null +++ b/src/test/ui/extern/extern-pass-char.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/extern/extern-pass-double.rs b/src/test/ui/extern/extern-pass-double.rs new file mode 100644 index 00000000000..dbd0a2dfa48 --- /dev/null +++ b/src/test/ui/extern/extern-pass-double.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/extern/extern-pass-empty.rs b/src/test/ui/extern/extern-pass-empty.rs new file mode 100644 index 00000000000..07099a24204 --- /dev/null +++ b/src/test/ui/extern/extern-pass-empty.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/extern/extern-pass-u32.rs b/src/test/ui/extern/extern-pass-u32.rs new file mode 100644 index 00000000000..f2efdb7d366 --- /dev/null +++ b/src/test/ui/extern/extern-pass-u32.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/extern/extern-pass-u64.rs b/src/test/ui/extern/extern-pass-u64.rs new file mode 100644 index 00000000000..975446d430c --- /dev/null +++ b/src/test/ui/extern/extern-pass-u64.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/extern/extern-prelude-core.rs b/src/test/ui/extern/extern-prelude-core.rs new file mode 100644 index 00000000000..f0d43404b00 --- /dev/null +++ b/src/test/ui/extern/extern-prelude-core.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(extern_prelude, 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/src/test/ui/extern/extern-prelude-core.stderr b/src/test/ui/extern/extern-prelude-core.stderr new file mode 100644 index 00000000000..f90eb933d3f --- /dev/null +++ b/src/test/ui/extern/extern-prelude-core.stderr @@ -0,0 +1,8 @@ +warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable + --> $DIR/extern-prelude-core.rs:2:12 + | +LL | #![feature(extern_prelude, lang_items, start)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(stable_features)]` on by default + diff --git a/src/test/ui/extern/extern-prelude-no-speculative.rs b/src/test/ui/extern/extern-prelude-no-speculative.rs new file mode 100644 index 00000000000..cc00737ab59 --- /dev/null +++ b/src/test/ui/extern/extern-prelude-no-speculative.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags: --extern LooksLikeExternCrate + +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/src/test/ui/extern/extern-prelude-std.rs b/src/test/ui/extern/extern-prelude-std.rs new file mode 100644 index 00000000000..3d28448ee86 --- /dev/null +++ b/src/test/ui/extern/extern-prelude-std.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(extern_prelude)] + +mod foo { + pub fn test() { + let x = std::cmp::min(2, 3); + assert_eq!(x, 2); + } +} + +fn main() { + foo::test(); +} diff --git a/src/test/ui/extern/extern-prelude-std.stderr b/src/test/ui/extern/extern-prelude-std.stderr new file mode 100644 index 00000000000..73b1dcfd5e1 --- /dev/null +++ b/src/test/ui/extern/extern-prelude-std.stderr @@ -0,0 +1,8 @@ +warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable + --> $DIR/extern-prelude-std.rs:2:12 + | +LL | #![feature(extern_prelude)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(stable_features)]` on by default + diff --git a/src/test/ui/extern/extern-pub.rs b/src/test/ui/extern/extern-pub.rs new file mode 100644 index 00000000000..c97e04b0755 --- /dev/null +++ b/src/test/ui/extern/extern-pub.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +extern { + pub fn free(p: *const u8); +} + +pub fn main() { +} diff --git a/src/test/ui/extern/extern-return-TwoU16s.rs b/src/test/ui/extern/extern-return-TwoU16s.rs new file mode 100644 index 00000000000..dd884ee77fe --- /dev/null +++ b/src/test/ui/extern/extern-return-TwoU16s.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/extern/extern-return-TwoU32s.rs b/src/test/ui/extern/extern-return-TwoU32s.rs new file mode 100644 index 00000000000..d6aaf5c9eaf --- /dev/null +++ b/src/test/ui/extern/extern-return-TwoU32s.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/extern/extern-return-TwoU64s.rs b/src/test/ui/extern/extern-return-TwoU64s.rs new file mode 100644 index 00000000000..c5e4ebadc18 --- /dev/null +++ b/src/test/ui/extern/extern-return-TwoU64s.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/extern/extern-return-TwoU8s.rs b/src/test/ui/extern/extern-return-TwoU8s.rs new file mode 100644 index 00000000000..a7cd21b2073 --- /dev/null +++ b/src/test/ui/extern/extern-return-TwoU8s.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/extern/extern-rust.rs b/src/test/ui/extern/extern-rust.rs new file mode 100644 index 00000000000..0cb190257be --- /dev/null +++ b/src/test/ui/extern/extern-rust.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/extern/extern-take-value.rs b/src/test/ui/extern/extern-take-value.rs new file mode 100644 index 00000000000..c09a774361f --- /dev/null +++ b/src/test/ui/extern/extern-take-value.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/extern/extern-thiscall.rs b/src/test/ui/extern/extern-thiscall.rs new file mode 100644 index 00000000000..e556c0512e9 --- /dev/null +++ b/src/test/ui/extern/extern-thiscall.rs @@ -0,0 +1,26 @@ +// run-pass +// ignore-arm +// ignore-aarch64 + +#![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/src/test/ui/extern/extern-types-inherent-impl.rs b/src/test/ui/extern/extern-types-inherent-impl.rs new file mode 100644 index 00000000000..fc98f55dc07 --- /dev/null +++ b/src/test/ui/extern/extern-types-inherent-impl.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// Test that inherent impls can be defined for extern types. + +#![feature(extern_types)] + +extern { + type A; +} + +impl A { + fn foo(&self) { } +} + +fn use_foo(x: &A) { + x.foo(); +} + +fn main() { } diff --git a/src/test/ui/extern/extern-types-manual-sync-send.rs b/src/test/ui/extern/extern-types-manual-sync-send.rs new file mode 100644 index 00000000000..ec63e5d40b9 --- /dev/null +++ b/src/test/ui/extern/extern-types-manual-sync-send.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/extern/extern-types-pointer-cast.rs b/src/test/ui/extern/extern-types-pointer-cast.rs new file mode 100644 index 00000000000..a4ebd3cf71e --- /dev/null +++ b/src/test/ui/extern/extern-types-pointer-cast.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/extern/extern-types-size_of_val.rs b/src/test/ui/extern/extern-types-size_of_val.rs new file mode 100644 index 00000000000..1c965609758 --- /dev/null +++ b/src/test/ui/extern/extern-types-size_of_val.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/extern/extern-types-thin-pointer.rs b/src/test/ui/extern/extern-types-thin-pointer.rs new file mode 100644 index 00000000000..83c35f7af78 --- /dev/null +++ b/src/test/ui/extern/extern-types-thin-pointer.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/extern/extern-types-trait-impl.rs b/src/test/ui/extern/extern-types-trait-impl.rs new file mode 100644 index 00000000000..6cce6c723c5 --- /dev/null +++ b/src/test/ui/extern/extern-types-trait-impl.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/extern/extern-vectorcall.rs b/src/test/ui/extern/extern-vectorcall.rs new file mode 100644 index 00000000000..1427a8f55cb --- /dev/null +++ b/src/test/ui/extern/extern-vectorcall.rs @@ -0,0 +1,26 @@ +// run-pass +// ignore-arm +// ignore-aarch64 + +#![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/src/test/ui/extern/extern_fat_drop.rs b/src/test/ui/extern/extern_fat_drop.rs new file mode 100644 index 00000000000..1cd12c2cab3 --- /dev/null +++ b/src/test/ui/extern/extern_fat_drop.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/extoption_env-not-defined.rs b/src/test/ui/extoption_env-not-defined.rs new file mode 100644 index 00000000000..4014902ffed --- /dev/null +++ b/src/test/ui/extoption_env-not-defined.rs @@ -0,0 +1,5 @@ +// run-pass + +pub fn main() { + assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none()); +} diff --git a/src/test/ui/fact.rs b/src/test/ui/fact.rs new file mode 100644 index 00000000000..c6c2f57e75c --- /dev/null +++ b/src/test/ui/fact.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/fat-lto.rs b/src/test/ui/fat-lto.rs new file mode 100644 index 00000000000..c8d8095a265 --- /dev/null +++ b/src/test/ui/fat-lto.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -Clto=fat +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} diff --git a/src/test/ui/fds-are-cloexec.rs b/src/test/ui/fds-are-cloexec.rs new file mode 100644 index 00000000000..2010b5b6680 --- /dev/null +++ b/src/test/ui/fds-are-cloexec.rs @@ -0,0 +1,83 @@ +// 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/src/test/ui/filter-block-view-items.rs b/src/test/ui/filter-block-view-items.rs new file mode 100644 index 00000000000..e63aa91577b --- /dev/null +++ b/src/test/ui/filter-block-view-items.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/fixup-deref-mut.rs b/src/test/ui/fixup-deref-mut.rs new file mode 100644 index 00000000000..6b2fd72b895 --- /dev/null +++ b/src/test/ui/fixup-deref-mut.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/for-loop-while/auto-loop.rs b/src/test/ui/for-loop-while/auto-loop.rs new file mode 100644 index 00000000000..f02ac43c734 --- /dev/null +++ b/src/test/ui/for-loop-while/auto-loop.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/for-loop-while/break-value.rs b/src/test/ui/for-loop-while/break-value.rs new file mode 100644 index 00000000000..9fc49fa8181 --- /dev/null +++ b/src/test/ui/for-loop-while/break-value.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/for-loop-while/break.rs b/src/test/ui/for-loop-while/break.rs new file mode 100644 index 00000000000..427b1b7a063 --- /dev/null +++ b/src/test/ui/for-loop-while/break.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/for-loop-while/for-destruct.rs b/src/test/ui/for-loop-while/for-destruct.rs new file mode 100644 index 00000000000..7ca8d4ded25 --- /dev/null +++ b/src/test/ui/for-loop-while/for-destruct.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/for-loop-while/for-loop-goofiness.rs b/src/test/ui/for-loop-while/for-loop-goofiness.rs new file mode 100644 index 00000000000..872ab168bb2 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-goofiness.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/for-loop-while/for-loop-has-unit-body.rs b/src/test/ui/for-loop-while/for-loop-has-unit-body.rs new file mode 100644 index 00000000000..38c34d2dc2e --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-has-unit-body.rs @@ -0,0 +1,13 @@ +// run-pass +fn main() { + // Check that the tail statement in the body unifies with something + for _ in 0..3 { + #[allow(deprecated)] + unsafe { std::mem::uninitialized() } + } + + // Check that the tail statement in the body can be unit + for _ in 0..3 { + () + } +} diff --git a/src/test/ui/for-loop-while/for-loop-into-iterator.rs b/src/test/ui/for-loop-while/for-loop-into-iterator.rs new file mode 100644 index 00000000000..199d4ddb299 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-into-iterator.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs b/src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs new file mode 100644 index 00000000000..6a38764a131 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/for-loop-while/for-loop-macro.rs b/src/test/ui/for-loop-while/for-loop-macro.rs new file mode 100644 index 00000000000..5abccd2a141 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-macro.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/for-loop-while/for-loop-mut-ref-element.rs b/src/test/ui/for-loop-while/for-loop-mut-ref-element.rs new file mode 100644 index 00000000000..a3d82ace9e2 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-mut-ref-element.rs @@ -0,0 +1,6 @@ +// 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/src/test/ui/for-loop-while/for-loop-no-std.rs b/src/test/ui/for-loop-while/for-loop-no-std.rs new file mode 100644 index 00000000000..65a33c5f16f --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-no-std.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/for-loop-while/for-loop-panic.rs b/src/test/ui/for-loop-while/for-loop-panic.rs new file mode 100644 index 00000000000..ac607d6d731 --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-panic.rs @@ -0,0 +1,4 @@ +// run-pass + + +pub fn main() { let x: Vec = Vec::new(); for _ in &x { panic!("moop"); } } diff --git a/src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs new file mode 100644 index 00000000000..a1e9b1ed87d --- /dev/null +++ b/src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators-break.rs b/src/test/ui/for-loop-while/foreach-external-iterators-break.rs new file mode 100644 index 00000000000..7de6a4f8acb --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators-break.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs new file mode 100644 index 00000000000..5d690807e05 --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs new file mode 100644 index 00000000000..9f2ca05cdb6 --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators-loop.rs b/src/test/ui/for-loop-while/foreach-external-iterators-loop.rs new file mode 100644 index 00000000000..78af195bc20 --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators-loop.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators-nested.rs b/src/test/ui/for-loop-while/foreach-external-iterators-nested.rs new file mode 100644 index 00000000000..8a95f160a1a --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators-nested.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/for-loop-while/foreach-external-iterators.rs b/src/test/ui/for-loop-while/foreach-external-iterators.rs new file mode 100644 index 00000000000..24ecfe9b60d --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-external-iterators.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/for-loop-while/foreach-nested.rs b/src/test/ui/for-loop-while/foreach-nested.rs new file mode 100644 index 00000000000..bb6edbc0797 --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-nested.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/for-loop-while/foreach-put-structured.rs b/src/test/ui/for-loop-while/foreach-put-structured.rs new file mode 100644 index 00000000000..3a47fcf3415 --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-put-structured.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/for-loop-while/foreach-simple-outer-slot.rs b/src/test/ui/for-loop-while/foreach-simple-outer-slot.rs new file mode 100644 index 00000000000..a8d42a789ba --- /dev/null +++ b/src/test/ui/for-loop-while/foreach-simple-outer-slot.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/for-loop-while/label_break_value.rs b/src/test/ui/for-loop-while/label_break_value.rs new file mode 100644 index 00000000000..eb5be7742e0 --- /dev/null +++ b/src/test/ui/for-loop-while/label_break_value.rs @@ -0,0 +1,116 @@ +// 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 { + 'e: { + 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/src/test/ui/for-loop-while/labeled-break.rs b/src/test/ui/for-loop-while/labeled-break.rs new file mode 100644 index 00000000000..4dacc57574f --- /dev/null +++ b/src/test/ui/for-loop-while/labeled-break.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/for-loop-while/linear-for-loop.rs b/src/test/ui/for-loop-while/linear-for-loop.rs new file mode 100644 index 00000000000..3c573db1d77 --- /dev/null +++ b/src/test/ui/for-loop-while/linear-for-loop.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs b/src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs new file mode 100644 index 00000000000..11b6971656f --- /dev/null +++ b/src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/for-loop-while/liveness-loop-break.rs b/src/test/ui/for-loop-while/liveness-loop-break.rs new file mode 100644 index 00000000000..60a63bccb10 --- /dev/null +++ b/src/test/ui/for-loop-while/liveness-loop-break.rs @@ -0,0 +1,13 @@ +// run-pass +fn test() { + let v; + loop { + v = 3; + break; + } + println!("{}", v); +} + +pub fn main() { + test(); +} diff --git a/src/test/ui/for-loop-while/liveness-move-in-loop.rs b/src/test/ui/for-loop-while/liveness-move-in-loop.rs new file mode 100644 index 00000000000..ce73d6335cb --- /dev/null +++ b/src/test/ui/for-loop-while/liveness-move-in-loop.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/for-loop-while/loop-break-cont-1.rs b/src/test/ui/for-loop-while/loop-break-cont-1.rs new file mode 100644 index 00000000000..f207746f085 --- /dev/null +++ b/src/test/ui/for-loop-while/loop-break-cont-1.rs @@ -0,0 +1,9 @@ +// run-pass + +pub fn main() { + let _i = 0_usize; + loop { + break; + } + assert!(true); +} diff --git a/src/test/ui/for-loop-while/loop-break-cont.rs b/src/test/ui/for-loop-while/loop-break-cont.rs new file mode 100644 index 00000000000..92d5a32c62b --- /dev/null +++ b/src/test/ui/for-loop-while/loop-break-cont.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/for-loop-while/loop-break-value.rs b/src/test/ui/for-loop-while/loop-break-value.rs new file mode 100644 index 00000000000..e1edbbb929e --- /dev/null +++ b/src/test/ui/for-loop-while/loop-break-value.rs @@ -0,0 +1,138 @@ +// 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/src/test/ui/for-loop-while/loop-diverges.rs b/src/test/ui/for-loop-while/loop-diverges.rs new file mode 100644 index 00000000000..f657bf9e0b3 --- /dev/null +++ b/src/test/ui/for-loop-while/loop-diverges.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/for-loop-while/loop-label-shadowing.rs b/src/test/ui/for-loop-while/loop-label-shadowing.rs new file mode 100644 index 00000000000..acb53e254bb --- /dev/null +++ b/src/test/ui/for-loop-while/loop-label-shadowing.rs @@ -0,0 +1,11 @@ +// run-pass +// Issue #12512. + +// pretty-expanded FIXME #23616 + +fn main() { + let mut foo = Vec::new(); + 'foo: for i in &[1, 2, 3] { + foo.push(*i); + } +} diff --git a/src/test/ui/for-loop-while/loop-labeled-break-value.rs b/src/test/ui/for-loop-while/loop-labeled-break-value.rs new file mode 100644 index 00000000000..cc8f826983b --- /dev/null +++ b/src/test/ui/for-loop-while/loop-labeled-break-value.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs b/src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs new file mode 100644 index 00000000000..1b5db20129d --- /dev/null +++ b/src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/for-loop-while/loop-scope.rs b/src/test/ui/for-loop-while/loop-scope.rs new file mode 100644 index 00000000000..73324a3e1bd --- /dev/null +++ b/src/test/ui/for-loop-while/loop-scope.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/for-loop-while/while-cont.rs b/src/test/ui/for-loop-while/while-cont.rs new file mode 100644 index 00000000000..a864e8ef70a --- /dev/null +++ b/src/test/ui/for-loop-while/while-cont.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/for-loop-while/while-flow-graph.rs b/src/test/ui/for-loop-while/while-flow-graph.rs new file mode 100644 index 00000000000..1748964a7b2 --- /dev/null +++ b/src/test/ui/for-loop-while/while-flow-graph.rs @@ -0,0 +1,6 @@ +// 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/src/test/ui/for-loop-while/while-label.rs b/src/test/ui/for-loop-while/while-label.rs new file mode 100644 index 00000000000..5abc41daf94 --- /dev/null +++ b/src/test/ui/for-loop-while/while-label.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/for-loop-while/while-let.rs b/src/test/ui/for-loop-while/while-let.rs new file mode 100644 index 00000000000..b9d70ff0b9d --- /dev/null +++ b/src/test/ui/for-loop-while/while-let.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/for-loop-while/while-loop-constraints-2.rs b/src/test/ui/for-loop-while/while-loop-constraints-2.rs new file mode 100644 index 00000000000..3c5cdf06cd8 --- /dev/null +++ b/src/test/ui/for-loop-while/while-loop-constraints-2.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/for-loop-while/while-prelude-drop.rs b/src/test/ui/for-loop-while/while-prelude-drop.rs new file mode 100644 index 00000000000..196b9daf6ec --- /dev/null +++ b/src/test/ui/for-loop-while/while-prelude-drop.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/for-loop-while/while-with-break.rs b/src/test/ui/for-loop-while/while-with-break.rs new file mode 100644 index 00000000000..a9d52dda544 --- /dev/null +++ b/src/test/ui/for-loop-while/while-with-break.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/for-loop-while/while.rs b/src/test/ui/for-loop-while/while.rs new file mode 100644 index 00000000000..90f718a3483 --- /dev/null +++ b/src/test/ui/for-loop-while/while.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/foreign/auxiliary/fn-abi.rs b/src/test/ui/foreign/auxiliary/fn-abi.rs new file mode 100644 index 00000000000..25c9e1b4ca3 --- /dev/null +++ b/src/test/ui/foreign/auxiliary/fn-abi.rs @@ -0,0 +1,2 @@ +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/ui/foreign/auxiliary/foreign_lib.rs b/src/test/ui/foreign/auxiliary/foreign_lib.rs new file mode 100644 index 00000000000..de6b0e2118a --- /dev/null +++ b/src/test/ui/foreign/auxiliary/foreign_lib.rs @@ -0,0 +1,38 @@ +#![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/src/test/ui/foreign/foreign-call-no-runtime.rs b/src/test/ui/foreign/foreign-call-no-runtime.rs new file mode 100644 index 00000000000..c6afa07ad05 --- /dev/null +++ b/src/test/ui/foreign/foreign-call-no-runtime.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/foreign/foreign-dupe.rs b/src/test/ui/foreign/foreign-dupe.rs new file mode 100644 index 00000000000..3c9f0f583d4 --- /dev/null +++ b/src/test/ui/foreign/foreign-dupe.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/foreign/foreign-fn-linkname.rs b/src/test/ui/foreign/foreign-fn-linkname.rs new file mode 100644 index 00000000000..1f048159064 --- /dev/null +++ b/src/test/ui/foreign/foreign-fn-linkname.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/foreign/foreign-fn-with-byval.rs b/src/test/ui/foreign/foreign-fn-with-byval.rs new file mode 100644 index 00000000000..3a35599aa57 --- /dev/null +++ b/src/test/ui/foreign/foreign-fn-with-byval.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/foreign/foreign-int-types.rs b/src/test/ui/foreign/foreign-int-types.rs new file mode 100644 index 00000000000..66296574d7d --- /dev/null +++ b/src/test/ui/foreign/foreign-int-types.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/foreign/foreign-mod-src/compiletest-ignore-dir b/src/test/ui/foreign/foreign-mod-src/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/foreign/foreign-mod-src/inner.rs b/src/test/ui/foreign/foreign-mod-src/inner.rs new file mode 100644 index 00000000000..cf484878b07 --- /dev/null +++ b/src/test/ui/foreign/foreign-mod-src/inner.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/foreign/foreign-mod-unused-const.rs b/src/test/ui/foreign/foreign-mod-unused-const.rs new file mode 100644 index 00000000000..d9efbe00e52 --- /dev/null +++ b/src/test/ui/foreign/foreign-mod-unused-const.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod foo { + extern { + pub static errno: u32; + } +} + +pub fn main() { +} diff --git a/src/test/ui/foreign/foreign-no-abi.rs b/src/test/ui/foreign/foreign-no-abi.rs new file mode 100644 index 00000000000..2f33fb47656 --- /dev/null +++ b/src/test/ui/foreign/foreign-no-abi.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/foreign/foreign-src/compiletest-ignore-dir b/src/test/ui/foreign/foreign-src/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/foreign/foreign-src/foreign.rs b/src/test/ui/foreign/foreign-src/foreign.rs new file mode 100644 index 00000000000..47016ad6ce7 --- /dev/null +++ b/src/test/ui/foreign/foreign-src/foreign.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/foreign/foreign-truncated-arguments.rs b/src/test/ui/foreign/foreign-truncated-arguments.rs new file mode 100644 index 00000000000..c61c2b587b6 --- /dev/null +++ b/src/test/ui/foreign/foreign-truncated-arguments.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/foreign/foreign2.rs b/src/test/ui/foreign/foreign2.rs new file mode 100644 index 00000000000..c1ab57776f6 --- /dev/null +++ b/src/test/ui/foreign/foreign2.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/format-hygiene.rs b/src/test/ui/format-hygiene.rs new file mode 100644 index 00000000000..6bf5ae8bead --- /dev/null +++ b/src/test/ui/format-hygiene.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(non_upper_case_globals)] +pub const arg0: u8 = 1; + +pub fn main() { + format!("{}", 1); +} diff --git a/src/test/ui/format-nan.rs b/src/test/ui/format-nan.rs new file mode 100644 index 00000000000..e4a134fa2fb --- /dev/null +++ b/src/test/ui/format-nan.rs @@ -0,0 +1,9 @@ +// run-pass + +pub fn main() { + use std::f64; + let x = "NaN".to_string(); + assert_eq!(format!("{}", f64::NAN), x); + assert_eq!(format!("{:e}", f64::NAN), x); + assert_eq!(format!("{:E}", f64::NAN), x); +} diff --git a/src/test/ui/format-no-std.rs b/src/test/ui/format-no-std.rs new file mode 100644 index 00000000000..c9b7651bfda --- /dev/null +++ b/src/test/ui/format-no-std.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/format-ref-cell.rs b/src/test/ui/format-ref-cell.rs new file mode 100644 index 00000000000..afb2f8488b8 --- /dev/null +++ b/src/test/ui/format-ref-cell.rs @@ -0,0 +1,10 @@ +// run-pass + +use std::cell::RefCell; + +pub fn main() { + let name = RefCell::new("rust"); + let what = RefCell::new("rocks"); + let msg = format!("{name} {}", &*what.borrow(), name=&*name.borrow()); + assert_eq!(msg, "rust rocks".to_string()); +} diff --git a/src/test/ui/fsu-moves-and-copies.rs b/src/test/ui/fsu-moves-and-copies.rs new file mode 100644 index 00000000000..c41bcc73fa5 --- /dev/null +++ b/src/test/ui/fsu-moves-and-copies.rs @@ -0,0 +1,95 @@ +// 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/src/test/ui/fun-call-variants.rs b/src/test/ui/fun-call-variants.rs new file mode 100644 index 00000000000..5b83e2620d8 --- /dev/null +++ b/src/test/ui/fun-call-variants.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/fun-indirect-call.rs b/src/test/ui/fun-indirect-call.rs new file mode 100644 index 00000000000..49da3d83f4a --- /dev/null +++ b/src/test/ui/fun-indirect-call.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/functions-closures/auxiliary/fn-abi.rs b/src/test/ui/functions-closures/auxiliary/fn-abi.rs new file mode 100644 index 00000000000..25c9e1b4ca3 --- /dev/null +++ b/src/test/ui/functions-closures/auxiliary/fn-abi.rs @@ -0,0 +1,2 @@ +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/ui/functions-closures/call-closure-from-overloaded-op.rs b/src/test/ui/functions-closures/call-closure-from-overloaded-op.rs new file mode 100644 index 00000000000..8e1c68fd77d --- /dev/null +++ b/src/test/ui/functions-closures/call-closure-from-overloaded-op.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/functions-closures/capture-clauses-boxed-closures.rs b/src/test/ui/functions-closures/capture-clauses-boxed-closures.rs new file mode 100644 index 00000000000..bcde504635d --- /dev/null +++ b/src/test/ui/functions-closures/capture-clauses-boxed-closures.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs b/src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs new file mode 100644 index 00000000000..206b3d7b613 --- /dev/null +++ b/src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/functions-closures/clone-closure.rs b/src/test/ui/functions-closures/clone-closure.rs new file mode 100644 index 00000000000..1e725d8056d --- /dev/null +++ b/src/test/ui/functions-closures/clone-closure.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs b/src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs new file mode 100644 index 00000000000..ccb2e201d7d --- /dev/null +++ b/src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/functions-closures/closure-expected-type/README.md b/src/test/ui/functions-closures/closure-expected-type/README.md new file mode 100644 index 00000000000..fd493e1ff37 --- /dev/null +++ b/src/test/ui/functions-closures/closure-expected-type/README.md @@ -0,0 +1,8 @@ +Some tests targeted at how we deduce the types of closure arguments. +This process is a result of some heuristics aimed at combining the +*expected type* we have with the *actual types* that we get from +inputs. This investigation was kicked off by #38714, which revealed +some pretty deep flaws in the ad-hoc way that we were doing things +before. + +See also `src/test/compile-fail/closure-expected-type`. diff --git a/src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs b/src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs new file mode 100644 index 00000000000..6d5a9876c37 --- /dev/null +++ b/src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/functions-closures/closure-expected-type/issue-38714.rs b/src/test/ui/functions-closures/closure-expected-type/issue-38714.rs new file mode 100644 index 00000000000..e97785b5cac --- /dev/null +++ b/src/test/ui/functions-closures/closure-expected-type/issue-38714.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs b/src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs new file mode 100644 index 00000000000..e9964531c3c --- /dev/null +++ b/src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs b/src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs new file mode 100644 index 00000000000..8665cfc21a7 --- /dev/null +++ b/src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/functions-closures/closure-immediate.rs b/src/test/ui/functions-closures/closure-immediate.rs new file mode 100644 index 00000000000..428fc6bdef3 --- /dev/null +++ b/src/test/ui/functions-closures/closure-immediate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/functions-closures/closure-inference.rs b/src/test/ui/functions-closures/closure-inference.rs new file mode 100644 index 00000000000..96878445245 --- /dev/null +++ b/src/test/ui/functions-closures/closure-inference.rs @@ -0,0 +1,11 @@ +// run-pass + + +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/src/test/ui/functions-closures/closure-inference2.rs b/src/test/ui/functions-closures/closure-inference2.rs new file mode 100644 index 00000000000..f2dfa5888aa --- /dev/null +++ b/src/test/ui/functions-closures/closure-inference2.rs @@ -0,0 +1,9 @@ +// run-pass +// Test a rather underspecified example: + + +pub fn main() { + let f = {|i| i}; + assert_eq!(f(2), 2); + assert_eq!(f(5), 5); +} diff --git a/src/test/ui/functions-closures/closure-reform.rs b/src/test/ui/functions-closures/closure-reform.rs new file mode 100644 index 00000000000..0bb6159ff4a --- /dev/null +++ b/src/test/ui/functions-closures/closure-reform.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/functions-closures/closure-returning-closure.rs b/src/test/ui/functions-closures/closure-returning-closure.rs new file mode 100644 index 00000000000..17db81687ab --- /dev/null +++ b/src/test/ui/functions-closures/closure-returning-closure.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + let f = |_||x, y| x+y; + assert_eq!(f(())(1, 2), 3); +} diff --git a/src/test/ui/functions-closures/closure-to-fn-coercion.rs b/src/test/ui/functions-closures/closure-to-fn-coercion.rs new file mode 100644 index 00000000000..4f43c2bb538 --- /dev/null +++ b/src/test/ui/functions-closures/closure-to-fn-coercion.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs b/src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs new file mode 100644 index 00000000000..e7a9383950f --- /dev/null +++ b/src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/functions-closures/copy-closure.rs b/src/test/ui/functions-closures/copy-closure.rs new file mode 100644 index 00000000000..72da02421b7 --- /dev/null +++ b/src/test/ui/functions-closures/copy-closure.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/functions-closures/fn-abi.rs b/src/test/ui/functions-closures/fn-abi.rs new file mode 100644 index 00000000000..900af9c1f66 --- /dev/null +++ b/src/test/ui/functions-closures/fn-abi.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/functions-closures/fn-bare-assign.rs b/src/test/ui/functions-closures/fn-bare-assign.rs new file mode 100644 index 00000000000..f5dab3c8402 --- /dev/null +++ b/src/test/ui/functions-closures/fn-bare-assign.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/functions-closures/fn-bare-coerce-to-block.rs b/src/test/ui/functions-closures/fn-bare-coerce-to-block.rs new file mode 100644 index 00000000000..922e016ddc8 --- /dev/null +++ b/src/test/ui/functions-closures/fn-bare-coerce-to-block.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/functions-closures/fn-bare-item.rs b/src/test/ui/functions-closures/fn-bare-item.rs new file mode 100644 index 00000000000..a6e6495a40a --- /dev/null +++ b/src/test/ui/functions-closures/fn-bare-item.rs @@ -0,0 +1,8 @@ +// run-pass +fn f() { + println!("This is a bare function"); +} + +pub fn main() { + f(); +} diff --git a/src/test/ui/functions-closures/fn-bare-size.rs b/src/test/ui/functions-closures/fn-bare-size.rs new file mode 100644 index 00000000000..2ba56eaaed4 --- /dev/null +++ b/src/test/ui/functions-closures/fn-bare-size.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/functions-closures/fn-bare-spawn.rs b/src/test/ui/functions-closures/fn-bare-spawn.rs new file mode 100644 index 00000000000..0d46fe22087 --- /dev/null +++ b/src/test/ui/functions-closures/fn-bare-spawn.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/functions-closures/fn-coerce-field.rs b/src/test/ui/functions-closures/fn-coerce-field.rs new file mode 100644 index 00000000000..38bde7b9e8f --- /dev/null +++ b/src/test/ui/functions-closures/fn-coerce-field.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/functions-closures/fn-item-type-cast.rs b/src/test/ui/functions-closures/fn-item-type-cast.rs new file mode 100644 index 00000000000..4d50ea97b8b --- /dev/null +++ b/src/test/ui/functions-closures/fn-item-type-cast.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/functions-closures/fn-item-type-coerce.rs b/src/test/ui/functions-closures/fn-item-type-coerce.rs new file mode 100644 index 00000000000..7a096764e45 --- /dev/null +++ b/src/test/ui/functions-closures/fn-item-type-coerce.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/functions-closures/fn-item-type-zero-sized.rs b/src/test/ui/functions-closures/fn-item-type-zero-sized.rs new file mode 100644 index 00000000000..bd9f1ed663d --- /dev/null +++ b/src/test/ui/functions-closures/fn-item-type-zero-sized.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/functions-closures/fn-lval.rs b/src/test/ui/functions-closures/fn-lval.rs new file mode 100644 index 00000000000..01079eea457 --- /dev/null +++ b/src/test/ui/functions-closures/fn-lval.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/functions-closures/fn-type-infer.rs b/src/test/ui/functions-closures/fn-type-infer.rs new file mode 100644 index 00000000000..fe6567f22b5 --- /dev/null +++ b/src/test/ui/functions-closures/fn-type-infer.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs b/src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs new file mode 100644 index 00000000000..4ac07123d9d --- /dev/null +++ b/src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/functions-closures/nullable-pointer-opt-closures.rs b/src/test/ui/functions-closures/nullable-pointer-opt-closures.rs new file mode 100644 index 00000000000..87dacfba25b --- /dev/null +++ b/src/test/ui/functions-closures/nullable-pointer-opt-closures.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/functions-closures/parallel-codegen-closures.rs b/src/test/ui/functions-closures/parallel-codegen-closures.rs new file mode 100644 index 00000000000..79759daba50 --- /dev/null +++ b/src/test/ui/functions-closures/parallel-codegen-closures.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/functions-closures/return-from-closure.rs b/src/test/ui/functions-closures/return-from-closure.rs new file mode 100644 index 00000000000..656a95f120a --- /dev/null +++ b/src/test/ui/functions-closures/return-from-closure.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/generator/addassign-yield.rs b/src/test/ui/generator/addassign-yield.rs new file mode 100644 index 00000000000..66f22bf31fc --- /dev/null +++ b/src/test/ui/generator/addassign-yield.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/generator/auxiliary/xcrate-reachable.rs b/src/test/ui/generator/auxiliary/xcrate-reachable.rs new file mode 100644 index 00000000000..33337f8038f --- /dev/null +++ b/src/test/ui/generator/auxiliary/xcrate-reachable.rs @@ -0,0 +1,14 @@ +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn msg() -> u32 { + 0 +} + +pub fn foo() -> impl Generator { + || { + yield; + return msg(); + } +} diff --git a/src/test/ui/generator/auxiliary/xcrate.rs b/src/test/ui/generator/auxiliary/xcrate.rs new file mode 100644 index 00000000000..613c495832f --- /dev/null +++ b/src/test/ui/generator/auxiliary/xcrate.rs @@ -0,0 +1,18 @@ +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::Generator; + +pub fn foo() -> impl Generator { + || { + if false { + yield; + } + } +} + +pub fn bar(t: T) -> Box + Unpin> { + Box::new(|| { + yield t; + }) +} diff --git a/src/test/ui/generator/borrow-in-tail-expr.rs b/src/test/ui/generator/borrow-in-tail-expr.rs new file mode 100644 index 00000000000..540f5e3e1dd --- /dev/null +++ b/src/test/ui/generator/borrow-in-tail-expr.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(generators)] + +fn main() { + let _a = || { + yield; + let a = String::new(); + a.len() + }; +} diff --git a/src/test/ui/generator/conditional-drop.rs b/src/test/ui/generator/conditional-drop.rs new file mode 100644 index 00000000000..907f7a3c06d --- /dev/null +++ b/src/test/ui/generator/conditional-drop.rs @@ -0,0 +1,58 @@ +// run-pass + +#![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/src/test/ui/generator/control-flow.rs b/src/test/ui/generator/control-flow.rs new file mode 100644 index 00000000000..df70e013bd3 --- /dev/null +++ b/src/test/ui/generator/control-flow.rs @@ -0,0 +1,50 @@ +// run-pass + +#![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 + 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/src/test/ui/generator/drop-and-replace.rs b/src/test/ui/generator/drop-and-replace.rs new file mode 100644 index 00000000000..bb33502815b --- /dev/null +++ b/src/test/ui/generator/drop-and-replace.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/generator/drop-env.rs b/src/test/ui/generator/drop-env.rs new file mode 100644 index 00000000000..ac4e0665628 --- /dev/null +++ b/src/test/ui/generator/drop-env.rs @@ -0,0 +1,63 @@ +// run-pass + +#![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/src/test/ui/generator/issue-44197.rs b/src/test/ui/generator/issue-44197.rs new file mode 100644 index 00000000000..6efaff50c1e --- /dev/null +++ b/src/test/ui/generator/issue-44197.rs @@ -0,0 +1,33 @@ +// 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 { + move || { + yield foo(&baz); + } +} + +fn foo2(_: &str) -> Result { + Err(()) +} + +fn bar2(baz: String) -> impl Generator { + 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/src/test/ui/generator/issue-52398.rs b/src/test/ui/generator/issue-52398.rs new file mode 100644 index 00000000000..54a1912582c --- /dev/null +++ b/src/test/ui/generator/issue-52398.rs @@ -0,0 +1,28 @@ +// 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 || { + 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 || { + yield *y.borrow(); + return "Done"; + }; +} diff --git a/src/test/ui/generator/issue-57084.rs b/src/test/ui/generator/issue-57084.rs new file mode 100644 index 00000000000..8aaa6a0e427 --- /dev/null +++ b/src/test/ui/generator/issue-57084.rs @@ -0,0 +1,28 @@ +// 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]; + || { + let _to_pin = with(move || println!("{:p}", data)); + loop { + yield + } + }; +} diff --git a/src/test/ui/generator/issue-58888.rs b/src/test/ui/generator/issue-58888.rs new file mode 100644 index 00000000000..43b37a9afc2 --- /dev/null +++ b/src/test/ui/generator/issue-58888.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: -g + +#![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/src/test/ui/generator/iterator-count.rs b/src/test/ui/generator/iterator-count.rs new file mode 100644 index 00000000000..ac7e122dd58 --- /dev/null +++ b/src/test/ui/generator/iterator-count.rs @@ -0,0 +1,44 @@ +// 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 + 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/src/test/ui/generator/live-upvar-across-yield.rs b/src/test/ui/generator/live-upvar-across-yield.rs new file mode 100644 index 00000000000..a1064165b2f --- /dev/null +++ b/src/test/ui/generator/live-upvar-across-yield.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/generator/match-bindings.rs b/src/test/ui/generator/match-bindings.rs new file mode 100644 index 00000000000..560d8e7103c --- /dev/null +++ b/src/test/ui/generator/match-bindings.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] + +#![feature(generators)] + +enum Enum { + A(String), + B +} + +fn main() { + || { + loop { + if let true = true { + match Enum::A(String::new()) { + Enum::A(_var) => {} + Enum::B => {} + } + } + yield; + } + }; +} diff --git a/src/test/ui/generator/nested_generators.rs b/src/test/ui/generator/nested_generators.rs new file mode 100644 index 00000000000..b56cce1dc44 --- /dev/null +++ b/src/test/ui/generator/nested_generators.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/generator/non-static-is-unpin.rs b/src/test/ui/generator/non-static-is-unpin.rs new file mode 100644 index 00000000000..96d0a8e2833 --- /dev/null +++ b/src/test/ui/generator/non-static-is-unpin.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/generator/overlap-locals.rs b/src/test/ui/generator/overlap-locals.rs new file mode 100644 index 00000000000..101c8714fa8 --- /dev/null +++ b/src/test/ui/generator/overlap-locals.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/generator/panic-drops.rs b/src/test/ui/generator/panic-drops.rs new file mode 100644 index 00000000000..5ac97585f4b --- /dev/null +++ b/src/test/ui/generator/panic-drops.rs @@ -0,0 +1,57 @@ +// run-pass + +// ignore-wasm32-bare compiled as 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/src/test/ui/generator/panic-safe.rs b/src/test/ui/generator/panic-safe.rs new file mode 100644 index 00000000000..5f6778674dc --- /dev/null +++ b/src/test/ui/generator/panic-safe.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/generator/pin-box-generator.rs b/src/test/ui/generator/pin-box-generator.rs new file mode 100644 index 00000000000..c3136f5c0ec --- /dev/null +++ b/src/test/ui/generator/pin-box-generator.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/generator/reborrow-mut-upvar.rs b/src/test/ui/generator/reborrow-mut-upvar.rs new file mode 100644 index 00000000000..785e38a7eb8 --- /dev/null +++ b/src/test/ui/generator/reborrow-mut-upvar.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(generators)] + +fn _run(bar: &mut i32) { + || { + { + let _baz = &*bar; + yield; + } + + *bar = 2; + }; +} + +fn main() {} diff --git a/src/test/ui/generator/resume-after-return.rs b/src/test/ui/generator/resume-after-return.rs new file mode 100644 index 00000000000..71a68ff684a --- /dev/null +++ b/src/test/ui/generator/resume-after-return.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/generator/size-moved-locals.rs b/src/test/ui/generator/size-moved-locals.rs new file mode 100644 index 00000000000..01db971434b --- /dev/null +++ b/src/test/ui/generator/size-moved-locals.rs @@ -0,0 +1,76 @@ +// 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 + +#![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!(1028, std::mem::size_of_val(&move_before_yield())); + assert_eq!(1032, std::mem::size_of_val(&move_before_yield_with_noop())); + assert_eq!(2056, std::mem::size_of_val(&overlap_move_points())); + assert_eq!(1032, std::mem::size_of_val(&overlap_x_and_y())); +} diff --git a/src/test/ui/generator/smoke.rs b/src/test/ui/generator/smoke.rs new file mode 100644 index 00000000000..533f2399084 --- /dev/null +++ b/src/test/ui/generator/smoke.rs @@ -0,0 +1,174 @@ +// run-pass + +// 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/src/test/ui/generator/static-generators.rs b/src/test/ui/generator/static-generators.rs new file mode 100644 index 00000000000..965d3c61c22 --- /dev/null +++ b/src/test/ui/generator/static-generators.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/generator/too-live-local-in-immovable-gen.rs b/src/test/ui/generator/too-live-local-in-immovable-gen.rs new file mode 100644 index 00000000000..f299a8aa72b --- /dev/null +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(unused_unsafe)] + +#![feature(generators)] + +fn main() { + unsafe { + static move || { + // 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/src/test/ui/generator/xcrate-reachable.rs b/src/test/ui/generator/xcrate-reachable.rs new file mode 100644 index 00000000000..9483ad7395e --- /dev/null +++ b/src/test/ui/generator/xcrate-reachable.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/generator/xcrate.rs b/src/test/ui/generator/xcrate.rs new file mode 100644 index 00000000000..febf5c3583f --- /dev/null +++ b/src/test/ui/generator/xcrate.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/generator/yield-in-args-rev.rs b/src/test/ui/generator/yield-in-args-rev.rs new file mode 100644 index 00000000000..f9ab981121a --- /dev/null +++ b/src/test/ui/generator/yield-in-args-rev.rs @@ -0,0 +1,19 @@ +// 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() { + || { + let b = true; + foo(yield, &b); + }; +} + +fn main() { } diff --git a/src/test/ui/generator/yield-in-box.rs b/src/test/ui/generator/yield-in-box.rs new file mode 100644 index 00000000000..d8475715c7c --- /dev/null +++ b/src/test/ui/generator/yield-in-box.rs @@ -0,0 +1,18 @@ +// run-pass + +// Test that box-statements with yields in them work. + +#![feature(generators, box_syntax)] + +fn main() { + let x = 0i32; + || { + let y = 2u32; + { + let _t = box (&x, yield 0, &y); + } + match box (&x, yield 0, &y) { + _t => {} + } + }; +} diff --git a/src/test/ui/generator/yield-in-initializer.rs b/src/test/ui/generator/yield-in-initializer.rs new file mode 100644 index 00000000000..8ff35d8ddf1 --- /dev/null +++ b/src/test/ui/generator/yield-in-initializer.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(generators)] + +fn main() { + static || { + 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/src/test/ui/generator/yield-subtype.rs b/src/test/ui/generator/yield-subtype.rs new file mode 100644 index 00000000000..fe88d424dd1 --- /dev/null +++ b/src/test/ui/generator/yield-subtype.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +#![allow(dead_code)] + +#![feature(generators)] + +fn bar<'a>() { + let a: &'static str = "hi"; + let b: &'a str = a; + + || { + yield a; + yield b; + }; +} + +fn main() {} diff --git a/src/test/ui/generics/auxiliary/default_type_params_xc.rs b/src/test/ui/generics/auxiliary/default_type_params_xc.rs new file mode 100644 index 00000000000..aacbd672ade --- /dev/null +++ b/src/test/ui/generics/auxiliary/default_type_params_xc.rs @@ -0,0 +1,5 @@ +pub struct Heap; + +pub struct FakeHeap; + +pub struct FakeVec { pub f: Option<(T,A)> } diff --git a/src/test/ui/generics/generic-alias-unique.rs b/src/test/ui/generics/generic-alias-unique.rs new file mode 100644 index 00000000000..76a184d8d25 --- /dev/null +++ b/src/test/ui/generics/generic-alias-unique.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/generics/generic-default-type-params-cross-crate.rs b/src/test/ui/generics/generic-default-type-params-cross-crate.rs new file mode 100644 index 00000000000..9e5eaa72c15 --- /dev/null +++ b/src/test/ui/generics/generic-default-type-params-cross-crate.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/generics/generic-default-type-params.rs b/src/test/ui/generics/generic-default-type-params.rs new file mode 100644 index 00000000000..afdd301fde9 --- /dev/null +++ b/src/test/ui/generics/generic-default-type-params.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/generics/generic-derived-type.rs b/src/test/ui/generics/generic-derived-type.rs new file mode 100644 index 00000000000..c643496fa7f --- /dev/null +++ b/src/test/ui/generics/generic-derived-type.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/generics/generic-exterior-unique.rs b/src/test/ui/generics/generic-exterior-unique.rs new file mode 100644 index 00000000000..9b3e1ee02a2 --- /dev/null +++ b/src/test/ui/generics/generic-exterior-unique.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/generics/generic-extern-mangle.rs b/src/test/ui/generics/generic-extern-mangle.rs new file mode 100644 index 00000000000..985a6f39cd7 --- /dev/null +++ b/src/test/ui/generics/generic-extern-mangle.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/generics/generic-fn-infer.rs b/src/test/ui/generics/generic-fn-infer.rs new file mode 100644 index 00000000000..9ba4224732b --- /dev/null +++ b/src/test/ui/generics/generic-fn-infer.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/generics/generic-fn-twice.rs b/src/test/ui/generics/generic-fn-twice.rs new file mode 100644 index 00000000000..2f25fc24ced --- /dev/null +++ b/src/test/ui/generics/generic-fn-twice.rs @@ -0,0 +1,11 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +mod foomod { + pub fn foo() { } +} + +pub fn main() { foomod::foo::(); foomod::foo::(); } diff --git a/src/test/ui/generics/generic-fn-unique.rs b/src/test/ui/generics/generic-fn-unique.rs new file mode 100644 index 00000000000..6cda1c3dc15 --- /dev/null +++ b/src/test/ui/generics/generic-fn-unique.rs @@ -0,0 +1,6 @@ +// 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/src/test/ui/generics/generic-fn.rs b/src/test/ui/generics/generic-fn.rs new file mode 100644 index 00000000000..8038fabc1ce --- /dev/null +++ b/src/test/ui/generics/generic-fn.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/generics/generic-ivec-leak.rs b/src/test/ui/generics/generic-ivec-leak.rs new file mode 100644 index 00000000000..a8ea1d5069b --- /dev/null +++ b/src/test/ui/generics/generic-ivec-leak.rs @@ -0,0 +1,5 @@ +// 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/src/test/ui/generics/generic-newtype-struct.rs b/src/test/ui/generics/generic-newtype-struct.rs new file mode 100644 index 00000000000..570c982cc87 --- /dev/null +++ b/src/test/ui/generics/generic-newtype-struct.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct S(T); + +pub fn main() { + let _s = S(2); +} diff --git a/src/test/ui/generics/generic-object.rs b/src/test/ui/generics/generic-object.rs new file mode 100644 index 00000000000..870ff980ec6 --- /dev/null +++ b/src/test/ui/generics/generic-object.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/generics/generic-recursive-tag.rs b/src/test/ui/generics/generic-recursive-tag.rs new file mode 100644 index 00000000000..e1875f0abbe --- /dev/null +++ b/src/test/ui/generics/generic-recursive-tag.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/generics/generic-static-methods.rs b/src/test/ui/generics/generic-static-methods.rs new file mode 100644 index 00000000000..b39fa081a65 --- /dev/null +++ b/src/test/ui/generics/generic-static-methods.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/generics/generic-tag-corruption.rs b/src/test/ui/generics/generic-tag-corruption.rs new file mode 100644 index 00000000000..aa26183a0d4 --- /dev/null +++ b/src/test/ui/generics/generic-tag-corruption.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/generics/generic-tag-local.rs b/src/test/ui/generics/generic-tag-local.rs new file mode 100644 index 00000000000..cc85e6e0f0a --- /dev/null +++ b/src/test/ui/generics/generic-tag-local.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/generics/generic-tag-match.rs b/src/test/ui/generics/generic-tag-match.rs new file mode 100644 index 00000000000..09ed6a808e6 --- /dev/null +++ b/src/test/ui/generics/generic-tag-match.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/generics/generic-tag-values.rs b/src/test/ui/generics/generic-tag-values.rs new file mode 100644 index 00000000000..230f477b6e9 --- /dev/null +++ b/src/test/ui/generics/generic-tag-values.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/generics/generic-tag.rs b/src/test/ui/generics/generic-tag.rs new file mode 100644 index 00000000000..74ef4eeba8a --- /dev/null +++ b/src/test/ui/generics/generic-tag.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/generics/generic-temporary.rs b/src/test/ui/generics/generic-temporary.rs new file mode 100644 index 00000000000..b63b534d03f --- /dev/null +++ b/src/test/ui/generics/generic-temporary.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/generics/generic-tup.rs b/src/test/ui/generics/generic-tup.rs new file mode 100644 index 00000000000..79ebd648cd4 --- /dev/null +++ b/src/test/ui/generics/generic-tup.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/generics/generic-type-synonym.rs b/src/test/ui/generics/generic-type-synonym.rs new file mode 100644 index 00000000000..4f181fbcc7e --- /dev/null +++ b/src/test/ui/generics/generic-type-synonym.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/generics/generic-type.rs b/src/test/ui/generics/generic-type.rs new file mode 100644 index 00000000000..aa46db07eee --- /dev/null +++ b/src/test/ui/generics/generic-type.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/generics/generic-unique.rs b/src/test/ui/generics/generic-unique.rs new file mode 100644 index 00000000000..d36504c75dd --- /dev/null +++ b/src/test/ui/generics/generic-unique.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/global-scope.rs b/src/test/ui/global-scope.rs new file mode 100644 index 00000000000..944eee5afc3 --- /dev/null +++ b/src/test/ui/global-scope.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/guards-not-exhaustive.rs b/src/test/ui/guards-not-exhaustive.rs new file mode 100644 index 00000000000..b74f162c0c6 --- /dev/null +++ b/src/test/ui/guards-not-exhaustive.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/guards.rs b/src/test/ui/guards.rs new file mode 100644 index 00000000000..10a4bb67387 --- /dev/null +++ b/src/test/ui/guards.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/hashmap-memory.rs b/src/test/ui/hashmap-memory.rs new file mode 100644 index 00000000000..3129eb0da82 --- /dev/null +++ b/src/test/ui/hashmap-memory.rs @@ -0,0 +1,94 @@ +// 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/src/test/ui/hello.rs b/src/test/ui/hello.rs new file mode 100644 index 00000000000..c207c25545e --- /dev/null +++ b/src/test/ui/hello.rs @@ -0,0 +1,5 @@ +// run-pass + +pub fn main() { + println!("hello, world"); +} diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs new file mode 100644 index 00000000000..cc766c0605c --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs new file mode 100644 index 00000000000..8431226a3ec --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs new file mode 100644 index 00000000000..ff84ad9d298 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.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 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/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs new file mode 100644 index 00000000000..afab9986ce2 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.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; +} + +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/src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs new file mode 100644 index 00000000000..04519f11600 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs new file mode 100644 index 00000000000..1fab9758c5c --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs new file mode 100644 index 00000000000..42247798f66 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs new file mode 100644 index 00000000000..6834c392d4e --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs new file mode 100644 index 00000000000..b97fdf4df50 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs new file mode 100644 index 00000000000..d8c726cdd71 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs new file mode 100644 index 00000000000..41ebb3f5a14 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs new file mode 100644 index 00000000000..a8f38180cc2 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs new file mode 100644 index 00000000000..a4a8a5ac6cc --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/html-literals.rs b/src/test/ui/html-literals.rs new file mode 100644 index 00000000000..ae45e97c8b0 --- /dev/null +++ b/src/test/ui/html-literals.rs @@ -0,0 +1,94 @@ +// 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/src/test/ui/if-bot.rs b/src/test/ui/if-bot.rs new file mode 100644 index 00000000000..0f09db530d4 --- /dev/null +++ b/src/test/ui/if-bot.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + let i: isize = if false { panic!() } else { 5 }; + println!("{}", i); +} diff --git a/src/test/ui/if-check.rs b/src/test/ui/if-check.rs new file mode 100644 index 00000000000..6593225e7dd --- /dev/null +++ b/src/test/ui/if-check.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/if-ret.rs b/src/test/ui/if-ret.rs new file mode 100644 index 00000000000..e1e795d83be --- /dev/null +++ b/src/test/ui/if-ret.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(unused_parens)] +// pretty-expanded FIXME #23616 + +fn foo() { if (return) { } } + +pub fn main() { foo(); } diff --git a/src/test/ui/ifmt.rs b/src/test/ui/ifmt.rs new file mode 100644 index 00000000000..841be20ef86 --- /dev/null +++ b/src/test/ui/ifmt.rs @@ -0,0 +1,323 @@ +// run-pass + +#![deny(warnings)] +#![allow(unused_must_use)] +#![allow(unused_features)] +#![feature(box_syntax)] + +use std::cell::RefCell; +use std::fmt::{self, Write}; +use std::usize; + +struct A; +struct B; +struct C; +struct D; + +impl fmt::LowerHex for A { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("aloha") + } +} +impl fmt::UpperHex for B { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("adios") + } +} +impl fmt::Display for C { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad_integral(true, "☃", "123") + } +} +impl fmt::Binary for D { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("aa")?; + f.write_char('☃')?; + f.write_str("bb") + } +} + +macro_rules! t { + ($a:expr, $b:expr) => { assert_eq!($a, $b) } +} + +pub fn main() { + // Various edge cases without formats + t!(format!(""), ""); + t!(format!("hello"), "hello"); + t!(format!("hello {{"), "hello {"); + + // default formatters should work + t!(format!("{}", 1.0f32), "1"); + t!(format!("{}", 1.0f64), "1"); + t!(format!("{}", "a"), "a"); + t!(format!("{}", "a".to_string()), "a"); + t!(format!("{}", false), "false"); + t!(format!("{}", 'a'), "a"); + + // At least exercise all the formats + t!(format!("{}", true), "true"); + t!(format!("{}", '☃'), "☃"); + t!(format!("{}", 10), "10"); + t!(format!("{}", 10_usize), "10"); + t!(format!("{:?}", '☃'), "'☃'"); + t!(format!("{:?}", 10), "10"); + t!(format!("{:?}", 10_usize), "10"); + t!(format!("{:?}", "true"), "\"true\""); + t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\""); + t!(format!("{:?}", "foo\n\"bar\"\r\n\'baz\'\t\\qux\\"), + r#""foo\n\"bar\"\r\n\'baz\'\t\\qux\\""#); + t!(format!("{:?}", "foo\0bar\x01baz\u{7f}q\u{75}x"), + r#""foo\u{0}bar\u{1}baz\u{7f}qux""#); + t!(format!("{:o}", 10_usize), "12"); + t!(format!("{:x}", 10_usize), "a"); + t!(format!("{:X}", 10_usize), "A"); + t!(format!("{}", "foo"), "foo"); + t!(format!("{}", "foo".to_string()), "foo"); + if cfg!(target_pointer_width = "32") { + t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234"); + t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234"); + } else { + t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234"); + t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234"); + } + t!(format!("{:p}", 0x1234 as *const isize), "0x1234"); + t!(format!("{:p}", 0x1234 as *mut isize), "0x1234"); + t!(format!("{:x}", A), "aloha"); + t!(format!("{:X}", B), "adios"); + t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃"); + t!(format!("{1} {0}", 0, 1), "1 0"); + t!(format!("{foo} {bar}", foo=0, bar=1), "0 1"); + t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0"); + t!(format!("{} {0}", "a"), "a a"); + t!(format!("{foo_bar}", foo_bar=1), "1"); + t!(format!("{}", 5 + 5), "10"); + t!(format!("{:#4}", C), "☃123"); + t!(format!("{:b}", D), "aa☃bb"); + + let a: &dyn fmt::Debug = &1; + t!(format!("{:?}", a), "1"); + + + // Formatting strings and their arguments + t!(format!("{}", "a"), "a"); + t!(format!("{:4}", "a"), "a "); + t!(format!("{:4}", "☃"), "☃ "); + t!(format!("{:>4}", "a"), " a"); + t!(format!("{:<4}", "a"), "a "); + t!(format!("{:^5}", "a"), " a "); + t!(format!("{:^5}", "aa"), " aa "); + t!(format!("{:^4}", "a"), " a "); + t!(format!("{:^4}", "aa"), " aa "); + t!(format!("{:.4}", "a"), "a"); + t!(format!("{:4.4}", "a"), "a "); + t!(format!("{:4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); + t!(format!("{:<4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); + t!(format!("{:>4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); + t!(format!("{:^4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa"); + t!(format!("{:>10.4}", "aaaaaaaaaaaaaaaaaa"), " aaaa"); + t!(format!("{:2.4}", "aaaaa"), "aaaa"); + t!(format!("{:2.4}", "aaaa"), "aaaa"); + t!(format!("{:2.4}", "aaa"), "aaa"); + t!(format!("{:2.4}", "aa"), "aa"); + t!(format!("{:2.4}", "a"), "a "); + t!(format!("{:0>2}", "a"), "0a"); + t!(format!("{:.*}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa"); + t!(format!("{:.1$}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa"); + t!(format!("{:.a$}", "aaaaaaaaaaaaaaaaaa", a=4), "aaaa"); + t!(format!("{:1$}", "a", 4), "a "); + t!(format!("{1:0$}", 4, "a"), "a "); + t!(format!("{:a$}", "a", a=4), "a "); + t!(format!("{:-#}", "a"), "a"); + t!(format!("{:+#}", "a"), "a"); + t!(format!("{:/^10.8}", "1234567890"), "/12345678/"); + + // Some float stuff + t!(format!("{:}", 1.0f32), "1"); + t!(format!("{:}", 1.0f64), "1"); + t!(format!("{:.3}", 1.0f64), "1.000"); + t!(format!("{:10.3}", 1.0f64), " 1.000"); + t!(format!("{:+10.3}", 1.0f64), " +1.000"); + t!(format!("{:+10.3}", -1.0f64), " -1.000"); + + t!(format!("{:e}", 1.2345e6f32), "1.2345e6"); + t!(format!("{:e}", 1.2345e6f64), "1.2345e6"); + t!(format!("{:E}", 1.2345e6f64), "1.2345E6"); + t!(format!("{:.3e}", 1.2345e6f64), "1.234e6"); + t!(format!("{:10.3e}", 1.2345e6f64), " 1.234e6"); + t!(format!("{:+10.3e}", 1.2345e6f64), " +1.234e6"); + t!(format!("{:+10.3e}", -1.2345e6f64), " -1.234e6"); + + // Float edge cases + t!(format!("{}", -0.0), "0"); + t!(format!("{:?}", -0.0), "-0.0"); + t!(format!("{:?}", 0.0), "0.0"); + + // sign aware zero padding + t!(format!("{:<3}", 1), "1 "); + t!(format!("{:>3}", 1), " 1"); + t!(format!("{:^3}", 1), " 1 "); + t!(format!("{:03}", 1), "001"); + t!(format!("{:<03}", 1), "001"); + t!(format!("{:>03}", 1), "001"); + t!(format!("{:^03}", 1), "001"); + t!(format!("{:+03}", 1), "+01"); + t!(format!("{:<+03}", 1), "+01"); + t!(format!("{:>+03}", 1), "+01"); + t!(format!("{:^+03}", 1), "+01"); + t!(format!("{:#05x}", 1), "0x001"); + t!(format!("{:<#05x}", 1), "0x001"); + t!(format!("{:>#05x}", 1), "0x001"); + t!(format!("{:^#05x}", 1), "0x001"); + t!(format!("{:05}", 1.2), "001.2"); + t!(format!("{:<05}", 1.2), "001.2"); + t!(format!("{:>05}", 1.2), "001.2"); + t!(format!("{:^05}", 1.2), "001.2"); + t!(format!("{:05}", -1.2), "-01.2"); + t!(format!("{:<05}", -1.2), "-01.2"); + t!(format!("{:>05}", -1.2), "-01.2"); + t!(format!("{:^05}", -1.2), "-01.2"); + t!(format!("{:+05}", 1.2), "+01.2"); + t!(format!("{:<+05}", 1.2), "+01.2"); + t!(format!("{:>+05}", 1.2), "+01.2"); + t!(format!("{:^+05}", 1.2), "+01.2"); + + // Ergonomic format_args! + t!(format!("{0:x} {0:X}", 15), "f F"); + t!(format!("{0:x} {0:X} {}", 15), "f F 15"); + // NOTE: For now the longer test cases must not be followed immediately by + // >1 empty lines, or the pretty printer will break. Since no one wants to + // touch the current pretty printer (#751), we have no choice but to work + // around it. Some of the following test cases are also affected. + t!(format!("{:x}{0:X}{a:x}{:X}{1:x}{a:X}", 13, 14, a=15), "dDfEeF"); + t!(format!("{a:x} {a:X}", a=15), "f F"); + + // And its edge cases + t!(format!("{a:.0$} {b:.0$} {0:.0$}\n{a:.c$} {b:.c$} {c:.c$}", + 4, a="abcdefg", b="hijklmn", c=3), + "abcd hijk 4\nabc hij 3"); + t!(format!("{a:.*} {0} {:.*}", 4, 3, "efgh", a="abcdef"), "abcd 4 efg"); + t!(format!("{:.a$} {a} {a:#x}", "aaaaaa", a=2), "aa 2 0x2"); + + + // Test that pointers don't get truncated. + { + let val = usize::MAX; + let exp = format!("{:#x}", val); + t!(format!("{:p}", val as *const isize), exp); + } + + // Escaping + t!(format!("{{"), "{"); + t!(format!("}}"), "}"); + + test_write(); + test_print(); + test_order(); + test_once(); + + // make sure that format! doesn't move out of local variables + let a: Box<_> = box 3; + format!("{}", a); + format!("{}", a); + + // make sure that format! doesn't cause spurious unused-unsafe warnings when + // it's inside of an outer unsafe block + unsafe { + let a: isize = ::std::mem::transmute(3_usize); + format!("{}", a); + } + + test_format_args(); + + // test that trailing commas are acceptable + format!("{}", "test",); + format!("{foo}", foo="test",); + + test_refcell(); +} + +// Basic test to make sure that we can invoke the `write!` macro with an +// fmt::Write instance. +fn test_write() { + let mut buf = String::new(); + write!(&mut buf, "{}", 3); + { + let w = &mut buf; + write!(w, "{foo}", foo=4); + write!(w, "{}", "hello"); + writeln!(w, "{}", "line"); + writeln!(w, "{foo}", foo="bar"); + w.write_char('☃'); + w.write_str("str"); + } + + t!(buf, "34helloline\nbar\n☃str"); +} + +// Just make sure that the macros are defined, there's not really a lot that we +// can do with them just yet (to test the output) +fn test_print() { + print!("hi"); + print!("{:?}", vec![0u8]); + println!("hello"); + println!("this is a {}", "test"); + println!("{foo}", foo="bar"); +} + +// Just make sure that the macros are defined, there's not really a lot that we +// can do with them just yet (to test the output) +fn test_format_args() { + let mut buf = String::new(); + { + let w = &mut buf; + write!(w, "{}", format_args!("{}", 1)); + write!(w, "{}", format_args!("test")); + write!(w, "{}", format_args!("{test}", test=3)); + } + let s = buf; + t!(s, "1test3"); + + let s = fmt::format(format_args!("hello {}", "world")); + t!(s, "hello world"); + let s = format!("{}: {}", "args were", format_args!("hello {}", "world")); + t!(s, "args were: hello world"); +} + +fn test_order() { + // Make sure format!() arguments are always evaluated in a left-to-right + // ordering + fn foo() -> isize { + static mut FOO: isize = 0; + unsafe { + FOO += 1; + FOO + } + } + assert_eq!(format!("{} {} {a} {b} {} {c}", + foo(), foo(), foo(), a=foo(), b=foo(), c=foo()), + "1 2 4 5 3 6".to_string()); +} + +fn test_once() { + // Make sure each argument are evaluated only once even though it may be + // formatted multiple times + fn foo() -> isize { + static mut FOO: isize = 0; + unsafe { + FOO += 1; + FOO + } + } + assert_eq!(format!("{0} {0} {0} {a} {a} {a}", foo(), a=foo()), + "1 1 1 2 2 2".to_string()); +} + +fn test_refcell() { + let refcell = RefCell::new(5); + assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }"); + let borrow = refcell.borrow_mut(); + assert_eq!(format!("{:?}", refcell), "RefCell { value: }"); + drop(borrow); + assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }"); +} diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs new file mode 100644 index 00000000000..8c046a289fa --- /dev/null +++ b/src/test/ui/ignore-all-the-things.rs @@ -0,0 +1,47 @@ +// run-pass + +#![allow(non_shorthand_field_patterns)] +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +#![feature(slice_patterns)] + +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/src/test/ui/impl-for-never.rs b/src/test/ui/impl-for-never.rs new file mode 100644 index 00000000000..c5f12981ecc --- /dev/null +++ b/src/test/ui/impl-for-never.rs @@ -0,0 +1,26 @@ +// run-pass +// Test that we can call static methods on ! both directly and when it appears in a generic + +#![feature(never_type)] + +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/src/test/ui/impl-inherent-non-conflict.rs b/src/test/ui/impl-inherent-non-conflict.rs new file mode 100644 index 00000000000..be524f87c9f --- /dev/null +++ b/src/test/ui/impl-inherent-non-conflict.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/impl-not-adjacent-to-type.rs b/src/test/ui/impl-not-adjacent-to-type.rs new file mode 100644 index 00000000000..97caf908387 --- /dev/null +++ b/src/test/ui/impl-not-adjacent-to-type.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/impl-privacy-xc-1.rs b/src/test/ui/impl-privacy-xc-1.rs new file mode 100644 index 00000000000..c9f7f09c7bd --- /dev/null +++ b/src/test/ui/impl-privacy-xc-1.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/impl-privacy-xc-2.rs b/src/test/ui/impl-privacy-xc-2.rs new file mode 100644 index 00000000000..390764588fc --- /dev/null +++ b/src/test/ui/impl-privacy-xc-2.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/impl-trait-in-bindings.rs b/src/test/ui/impl-trait-in-bindings.rs new file mode 100644 index 00000000000..2e9b6cd5c78 --- /dev/null +++ b/src/test/ui/impl-trait-in-bindings.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + +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/src/test/ui/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait-in-bindings.stderr new file mode 100644 index 00000000000..54b42a102fa --- /dev/null +++ b/src/test/ui/impl-trait-in-bindings.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/impl-trait-in-bindings.rs:3:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/impl-trait/auxiliary/xcrate.rs b/src/test/ui/impl-trait/auxiliary/xcrate.rs new file mode 100644 index 00000000000..ac016258b7f --- /dev/null +++ b/src/test/ui/impl-trait/auxiliary/xcrate.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/impl-trait/bounds_regression.rs b/src/test/ui/impl-trait/bounds_regression.rs new file mode 100644 index 00000000000..0fdeb6bdee1 --- /dev/null +++ b/src/test/ui/impl-trait/bounds_regression.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/impl-trait/example-calendar.rs b/src/test/ui/impl-trait/example-calendar.rs new file mode 100644 index 00000000000..f1b1656745e --- /dev/null +++ b/src/test/ui/impl-trait/example-calendar.rs @@ -0,0 +1,857 @@ +// run-pass + +#![feature(fn_traits, + step_trait, + unboxed_closures, +)] + +//! Derived from: . +//! +//! Originally converted to Rust by [Daniel Keep](https://github.com/DanielKeep). + +use std::fmt::Write; +use std::mem; + +/// 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() + } +} + +impl std::iter::Step for NaiveDate { + fn steps_between(_: &Self, _: &Self) -> Option { + unimplemented!() + } + + fn replace_one(&mut self) -> Self { + mem::replace(self, NaiveDate(0, 0, 1)) + } + + fn replace_zero(&mut self) -> Self { + mem::replace(self, NaiveDate(0, 0, 0)) + } + + fn add_one(&self) -> Self { + self.succ() + } + + fn sub_one(&self) -> Self { + unimplemented!() + } + + fn add_usize(&self, _: usize) -> Option { + unimplemented!() + } + + fn sub_usize(&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/src/test/ui/impl-trait/example-st.rs b/src/test/ui/impl-trait/example-st.rs new file mode 100644 index 00000000000..4e1aa3a0859 --- /dev/null +++ b/src/test/ui/impl-trait/example-st.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/impl-trait/lifetimes.rs b/src/test/ui/impl-trait/lifetimes.rs new file mode 100644 index 00000000000..9a9843375e4 --- /dev/null +++ b/src/test/ui/impl-trait/lifetimes.rs @@ -0,0 +1,123 @@ +// 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/src/test/ui/impl-trait/nesting.rs b/src/test/ui/impl-trait/nesting.rs new file mode 100644 index 00000000000..27bdd5fa483 --- /dev/null +++ b/src/test/ui/impl-trait/nesting.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/impl-trait/universal_hrtb_anon.rs b/src/test/ui/impl-trait/universal_hrtb_anon.rs new file mode 100644 index 00000000000..30c8d291f6a --- /dev/null +++ b/src/test/ui/impl-trait/universal_hrtb_anon.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/impl-trait/universal_hrtb_named.rs b/src/test/ui/impl-trait/universal_hrtb_named.rs new file mode 100644 index 00000000000..07ff5d23e0c --- /dev/null +++ b/src/test/ui/impl-trait/universal_hrtb_named.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/impl-trait/universal_in_adt_in_parameters.rs b/src/test/ui/impl-trait/universal_in_adt_in_parameters.rs new file mode 100644 index 00000000000..a3829133dfa --- /dev/null +++ b/src/test/ui/impl-trait/universal_in_adt_in_parameters.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs new file mode 100644 index 00000000000..e98912d95a5 --- /dev/null +++ b/src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs new file mode 100644 index 00000000000..23c217a8f8b --- /dev/null +++ b/src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/impl-trait/universal_multiple_bounds.rs b/src/test/ui/impl-trait/universal_multiple_bounds.rs new file mode 100644 index 00000000000..40c1405c39b --- /dev/null +++ b/src/test/ui/impl-trait/universal_multiple_bounds.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/impl-trait/xcrate.rs b/src/test/ui/impl-trait/xcrate.rs new file mode 100644 index 00000000000..b73d2946c2b --- /dev/null +++ b/src/test/ui/impl-trait/xcrate.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/impl-trait/xcrate_simple.rs b/src/test/ui/impl-trait/xcrate_simple.rs new file mode 100644 index 00000000000..2b1fc97e321 --- /dev/null +++ b/src/test/ui/impl-trait/xcrate_simple.rs @@ -0,0 +1,9 @@ +// run-pass + +// aux-build:xcrate.rs + +extern crate xcrate; + +fn main() { + xcrate::return_internal_fn()(); +} diff --git a/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs new file mode 100644 index 00000000000..b76c1680bba --- /dev/null +++ b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs @@ -0,0 +1,20 @@ +#![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/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs new file mode 100644 index 00000000000..63611c24299 --- /dev/null +++ b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs @@ -0,0 +1,7 @@ +macro_rules! add1 { + ($e:expr) => ({ + let a = 1 + $e; + let b = $e + 1; + a + b - 1 + }) +} diff --git a/src/test/ui/imports/import-crate-with-invalid-spans/main.rs b/src/test/ui/imports/import-crate-with-invalid-spans/main.rs new file mode 100644 index 00000000000..64a4deca8c3 --- /dev/null +++ b/src/test/ui/imports/import-crate-with-invalid-spans/main.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/imports/import-from.rs b/src/test/ui/imports/import-from.rs new file mode 100644 index 00000000000..2817977b393 --- /dev/null +++ b/src/test/ui/imports/import-from.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/imports/import-glob-1.rs b/src/test/ui/imports/import-glob-1.rs new file mode 100644 index 00000000000..fcc0b63f101 --- /dev/null +++ b/src/test/ui/imports/import-glob-1.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/imports/import-glob-crate.rs b/src/test/ui/imports/import-glob-crate.rs new file mode 100644 index 00000000000..501392b7829 --- /dev/null +++ b/src/test/ui/imports/import-glob-crate.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/imports/import-in-block.rs b/src/test/ui/imports/import-in-block.rs new file mode 100644 index 00000000000..c0ba6220b54 --- /dev/null +++ b/src/test/ui/imports/import-in-block.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + use std::mem::replace; + let mut x = 5; + replace(&mut x, 6); + { + use std::mem::*; + let mut y = 6; + swap(&mut x, &mut y); + } +} diff --git a/src/test/ui/imports/import-prefix-macro.rs b/src/test/ui/imports/import-prefix-macro.rs new file mode 100644 index 00000000000..d770bb0da80 --- /dev/null +++ b/src/test/ui/imports/import-prefix-macro.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/imports/import-rename.rs b/src/test/ui/imports/import-rename.rs new file mode 100644 index 00000000000..9ad2b34b837 --- /dev/null +++ b/src/test/ui/imports/import-rename.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/imports/import-trailing-comma.rs b/src/test/ui/imports/import-trailing-comma.rs new file mode 100644 index 00000000000..f65c5c866a3 --- /dev/null +++ b/src/test/ui/imports/import-trailing-comma.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/imports/import.rs b/src/test/ui/imports/import.rs new file mode 100644 index 00000000000..de8bf626114 --- /dev/null +++ b/src/test/ui/imports/import.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/imports/import2.rs b/src/test/ui/imports/import2.rs new file mode 100644 index 00000000000..7b70f799ebf --- /dev/null +++ b/src/test/ui/imports/import2.rs @@ -0,0 +1,9 @@ +// run-pass + +use zed::bar; + +mod zed { + pub fn bar() { println!("bar"); } +} + +pub fn main() { bar(); } diff --git a/src/test/ui/imports/import3.rs b/src/test/ui/imports/import3.rs new file mode 100644 index 00000000000..17797aed359 --- /dev/null +++ b/src/test/ui/imports/import3.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/imports/import4.rs b/src/test/ui/imports/import4.rs new file mode 100644 index 00000000000..4fda5386112 --- /dev/null +++ b/src/test/ui/imports/import4.rs @@ -0,0 +1,9 @@ +// run-pass + +use zed::bar; + +mod zed { + pub fn bar() { println!("bar"); } +} + +pub fn main() { let _zed = 42; bar(); } diff --git a/src/test/ui/imports/import5.rs b/src/test/ui/imports/import5.rs new file mode 100644 index 00000000000..be2a55c2d41 --- /dev/null +++ b/src/test/ui/imports/import5.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/imports/import6.rs b/src/test/ui/imports/import6.rs new file mode 100644 index 00000000000..e11b28531f9 --- /dev/null +++ b/src/test/ui/imports/import6.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/imports/import7.rs b/src/test/ui/imports/import7.rs new file mode 100644 index 00000000000..aca7fbdc4f5 --- /dev/null +++ b/src/test/ui/imports/import7.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/imports/import8.rs b/src/test/ui/imports/import8.rs new file mode 100644 index 00000000000..87f0986bae4 --- /dev/null +++ b/src/test/ui/imports/import8.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/imports/imports.rs b/src/test/ui/imports/imports.rs new file mode 100644 index 00000000000..acb2b32b59d --- /dev/null +++ b/src/test/ui/imports/imports.rs @@ -0,0 +1,66 @@ +// 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/src/test/ui/in-band-lifetimes.rs b/src/test/ui/in-band-lifetimes.rs new file mode 100644 index 00000000000..c9f7d28699e --- /dev/null +++ b/src/test/ui/in-band-lifetimes.rs @@ -0,0 +1,96 @@ +// 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 existential_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { + x +} +fn existential_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { + x +} +fn existential_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { + x +} +fn existential_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { + x +} +fn existential_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { + x +} + +fn main() {} diff --git a/src/test/ui/inc-range-pat.rs b/src/test/ui/inc-range-pat.rs new file mode 100644 index 00000000000..1eb7dd0aa3e --- /dev/null +++ b/src/test/ui/inc-range-pat.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/infer-fn-tail-expr.rs b/src/test/ui/infer-fn-tail-expr.rs new file mode 100644 index 00000000000..413b1877a29 --- /dev/null +++ b/src/test/ui/infer-fn-tail-expr.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(dead_code)] +// issue #680 + + +// pretty-expanded FIXME #23616 + +fn f() -> Vec { Vec::new() } + +pub fn main() { } diff --git a/src/test/ui/inherit-env.rs b/src/test/ui/inherit-env.rs new file mode 100644 index 00000000000..e29fa04bbd5 --- /dev/null +++ b/src/test/ui/inherit-env.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/init-large-type.rs b/src/test/ui/init-large-type.rs new file mode 100644 index 00000000000..a304fc9356b --- /dev/null +++ b/src/test/ui/init-large-type.rs @@ -0,0 +1,26 @@ +// 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::thread; + +extern "rust-intrinsic" { + pub fn init() -> T; +} + +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 { init() }; + }).join(); +} diff --git a/src/test/ui/init-res-into-things.rs b/src/test/ui/init-res-into-things.rs new file mode 100644 index 00000000000..ed0c600c1d2 --- /dev/null +++ b/src/test/ui/init-res-into-things.rs @@ -0,0 +1,82 @@ +// 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/src/test/ui/inlined-main.rs b/src/test/ui/inlined-main.rs new file mode 100644 index 00000000000..75ff4c87dc6 --- /dev/null +++ b/src/test/ui/inlined-main.rs @@ -0,0 +1,4 @@ +// run-pass + +#[inline(always)] +fn main() {} diff --git a/src/test/ui/inner-attrs-on-impl.rs b/src/test/ui/inner-attrs-on-impl.rs new file mode 100644 index 00000000000..636e8c4885e --- /dev/null +++ b/src/test/ui/inner-attrs-on-impl.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/inner-module.rs b/src/test/ui/inner-module.rs new file mode 100644 index 00000000000..363f753e248 --- /dev/null +++ b/src/test/ui/inner-module.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/inner-static.rs b/src/test/ui/inner-static.rs new file mode 100644 index 00000000000..adba299ebe2 --- /dev/null +++ b/src/test/ui/inner-static.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/instantiable.rs b/src/test/ui/instantiable.rs new file mode 100644 index 00000000000..ad0cf3f4ac9 --- /dev/null +++ b/src/test/ui/instantiable.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs b/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs new file mode 100644 index 00000000000..f65f359875b --- /dev/null +++ b/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs @@ -0,0 +1,14 @@ +#![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/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs new file mode 100644 index 00000000000..6a67d04a54c --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-alignment.rs @@ -0,0 +1,74 @@ +// 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"))] +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] + #[cfg(target_arch = "x86")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 8); + } + } + + #[main] + #[cfg(target_arch = "x86_64")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 8); + } + } +} diff --git a/src/test/ui/intrinsics/intrinsic-assume.rs b/src/test/ui/intrinsics/intrinsic-assume.rs new file mode 100644 index 00000000000..3c9d70cb556 --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-assume.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/intrinsics/intrinsic-atomics-cc.rs b/src/test/ui/intrinsics/intrinsic-atomics-cc.rs new file mode 100644 index 00000000000..52e891da9ba --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-atomics-cc.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/intrinsics/intrinsic-atomics.rs b/src/test/ui/intrinsics/intrinsic-atomics.rs new file mode 100644 index 00000000000..608cf3dee52 --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-atomics.rs @@ -0,0 +1,103 @@ +// 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/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs b/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs new file mode 100644 index 00000000000..a2068429af5 --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs @@ -0,0 +1,190 @@ +// run-pass +#![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/src/test/ui/intrinsics/intrinsic-move-val.rs b/src/test/ui/intrinsics/intrinsic-move-val.rs new file mode 100644 index 00000000000..75b4ec365fe --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-move-val.rs @@ -0,0 +1,82 @@ +// run-pass + +#![feature(box_syntax)] +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn init() -> T; + pub fn move_val_init(dst: *mut T, src: T); + } +} + +pub fn main() { + unsafe { + // sanity check + check_drops_state(0, None); + + let mut x: Box = box D(1); + assert_eq!(x.0, 1); + + // A normal overwrite, to demonstrate `check_drops_state`. + x = 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: Box = rusti::init(); + + // 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.0, 2); + y.0 = 3; + assert_eq!(y.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/src/test/ui/intrinsics/intrinsic-unreachable.rs b/src/test/ui/intrinsics/intrinsic-unreachable.rs new file mode 100644 index 00000000000..da1a32d58ea --- /dev/null +++ b/src/test/ui/intrinsics/intrinsic-unreachable.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs new file mode 100644 index 00000000000..0154f049950 --- /dev/null +++ b/src/test/ui/intrinsics/intrinsics-integer.rs @@ -0,0 +1,172 @@ +// run-pass +// ignore-emscripten no i128 support + +#![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/src/test/ui/intrinsics/intrinsics-math.rs b/src/test/ui/intrinsics/intrinsics-math.rs new file mode 100644 index 00000000000..aea9fde6915 --- /dev/null +++ b/src/test/ui/intrinsics/intrinsics-math.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/invalid_const_promotion.rs b/src/test/ui/invalid_const_promotion.rs new file mode 100644 index 00000000000..6d59bb385dc --- /dev/null +++ b/src/test/ui/invalid_const_promotion.rs @@ -0,0 +1,56 @@ +// run-pass + +#![allow(unused_mut)] +// ignore-wasm32 +// ignore-emscripten +// ignore-sgx no processes + +// compile-flags: -C debug_assertions=yes + +#![stable(feature = "rustc", since = "1.0.0")] +#![feature(const_fn, rustc_private, staged_api, rustc_attrs)] +#![allow(const_err)] + +extern crate libc; + +use std::env; +use std::process::{Command, Stdio}; + +// this will panic in debug mode and overflow in release mode +#[stable(feature = "rustc", since = "1.0.0")] +#[rustc_promotable] +const fn bar() -> usize { 0 - 1 } + +fn foo() { + let _: &'static _ = &bar(); +} + +#[cfg(unix)] +fn check_status(status: std::process::ExitStatus) +{ + use std::os::unix::process::ExitStatusExt; + + assert!(status.signal() == Some(libc::SIGILL) + || status.signal() == Some(libc::SIGTRAP) + || 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] == "test" { + foo(); + return; + } + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("test").output().unwrap(); + check_status(p.status); +} diff --git a/src/test/ui/invoke-external-foreign.rs b/src/test/ui/invoke-external-foreign.rs new file mode 100644 index 00000000000..dbd2b4ad865 --- /dev/null +++ b/src/test/ui/invoke-external-foreign.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/irrefutable-unit.rs b/src/test/ui/irrefutable-unit.rs new file mode 100644 index 00000000000..dd8f03b6dbd --- /dev/null +++ b/src/test/ui/irrefutable-unit.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let ((),()) = ((),()); +} diff --git a/src/test/ui/issue-59020.rs b/src/test/ui/issue-59020.rs new file mode 100644 index 00000000000..e7544934da0 --- /dev/null +++ b/src/test/ui/issue-59020.rs @@ -0,0 +1,28 @@ +// edition:2018 +// run-pass +// ignore-emscripten no threads support +// ignore-sgx no thread sleep 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/src/test/ui/issues/.gitattributes b/src/test/ui/issues/.gitattributes new file mode 100644 index 00000000000..4517a4a2f1e --- /dev/null +++ b/src/test/ui/issues/.gitattributes @@ -0,0 +1 @@ +issue-16278.rs -text diff --git a/src/test/ui/issues/auxiliary/cgu_test.rs b/src/test/ui/issues/auxiliary/cgu_test.rs new file mode 100644 index 00000000000..5ed973164a1 --- /dev/null +++ b/src/test/ui/issues/auxiliary/cgu_test.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic +// compile-flags: --crate-type=lib + +pub fn id(t: T) -> T { + t +} diff --git a/src/test/ui/issues/auxiliary/cgu_test_a.rs b/src/test/ui/issues/auxiliary/cgu_test_a.rs new file mode 100644 index 00000000000..a3dcd92012e --- /dev/null +++ b/src/test/ui/issues/auxiliary/cgu_test_a.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/auxiliary/cgu_test_b.rs b/src/test/ui/issues/auxiliary/cgu_test_b.rs new file mode 100644 index 00000000000..a3dcd92012e --- /dev/null +++ b/src/test/ui/issues/auxiliary/cgu_test_b.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/auxiliary/i8.rs b/src/test/ui/issues/auxiliary/i8.rs new file mode 100644 index 00000000000..889a9c4ebb1 --- /dev/null +++ b/src/test/ui/issues/auxiliary/i8.rs @@ -0,0 +1,3 @@ +// A crate named after a built-in type. + +pub struct Test; diff --git a/src/test/ui/issues/auxiliary/iss.rs b/src/test/ui/issues/auxiliary/iss.rs new file mode 100644 index 00000000000..cf32f6c2d5d --- /dev/null +++ b/src/test/ui/issues/auxiliary/iss.rs @@ -0,0 +1,12 @@ +#![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/src/test/ui/issues/auxiliary/issue-10028.rs b/src/test/ui/issues/auxiliary/issue-10028.rs new file mode 100644 index 00000000000..135f26f4047 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-10028.rs @@ -0,0 +1,9 @@ +pub struct ZeroLengthThingWithDestructor; +impl Drop for ZeroLengthThingWithDestructor { + fn drop(&mut self) {} +} +impl ZeroLengthThingWithDestructor { + pub fn new() -> ZeroLengthThingWithDestructor { + ZeroLengthThingWithDestructor + } +} diff --git a/src/test/ui/issues/auxiliary/issue-10031-aux.rs b/src/test/ui/issues/auxiliary/issue-10031-aux.rs new file mode 100644 index 00000000000..e2abeb99ea8 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-10031-aux.rs @@ -0,0 +1 @@ +pub struct Wrap(pub A); diff --git a/src/test/ui/issues/auxiliary/issue-11224.rs b/src/test/ui/issues/auxiliary/issue-11224.rs new file mode 100644 index 00000000000..63543621a80 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11224.rs @@ -0,0 +1,16 @@ +#![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/src/test/ui/issues/auxiliary/issue-11225-1.rs b/src/test/ui/issues/auxiliary/issue-11225-1.rs new file mode 100644 index 00000000000..2c6f899a0f4 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11225-1.rs @@ -0,0 +1,18 @@ +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/src/test/ui/issues/auxiliary/issue-11225-2.rs b/src/test/ui/issues/auxiliary/issue-11225-2.rs new file mode 100644 index 00000000000..4381f0a4edf --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11225-2.rs @@ -0,0 +1,28 @@ +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/src/test/ui/issues/auxiliary/issue-11225-3.rs b/src/test/ui/issues/auxiliary/issue-11225-3.rs new file mode 100644 index 00000000000..266e42a10b5 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11225-3.rs @@ -0,0 +1,28 @@ +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/src/test/ui/issues/auxiliary/issue-11508.rs b/src/test/ui/issues/auxiliary/issue-11508.rs new file mode 100644 index 00000000000..16bfc65c2b5 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11508.rs @@ -0,0 +1,10 @@ +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/src/test/ui/issues/auxiliary/issue-11529.rs b/src/test/ui/issues/auxiliary/issue-11529.rs new file mode 100644 index 00000000000..dd3ef438705 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-11529.rs @@ -0,0 +1 @@ +pub struct A<'a>(pub &'a isize); diff --git a/src/test/ui/issues/auxiliary/issue-12133-dylib.rs b/src/test/ui/issues/auxiliary/issue-12133-dylib.rs new file mode 100644 index 00000000000..8bd2b3353b8 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12133-dylib.rs @@ -0,0 +1 @@ +#![crate_type = "dylib"] diff --git a/src/test/ui/issues/auxiliary/issue-12133-dylib2.rs b/src/test/ui/issues/auxiliary/issue-12133-dylib2.rs new file mode 100644 index 00000000000..30de7400600 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12133-dylib2.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "dylib"] + +extern crate issue_12133_rlib as a; +extern crate issue_12133_dylib as b; diff --git a/src/test/ui/issues/auxiliary/issue-12133-rlib.rs b/src/test/ui/issues/auxiliary/issue-12133-rlib.rs new file mode 100644 index 00000000000..39c261e1162 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12133-rlib.rs @@ -0,0 +1,3 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] diff --git a/src/test/ui/issues/auxiliary/issue-12612-1.rs b/src/test/ui/issues/auxiliary/issue-12612-1.rs new file mode 100644 index 00000000000..01f5a784bb7 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12612-1.rs @@ -0,0 +1,3 @@ +pub mod bar { + pub fn foo() {} +} diff --git a/src/test/ui/issues/auxiliary/issue-12612-2.rs b/src/test/ui/issues/auxiliary/issue-12612-2.rs new file mode 100644 index 00000000000..2c724787193 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12612-2.rs @@ -0,0 +1 @@ +pub fn baz() {} diff --git a/src/test/ui/issues/auxiliary/issue-12660-aux.rs b/src/test/ui/issues/auxiliary/issue-12660-aux.rs new file mode 100644 index 00000000000..6dea8662dfe --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-12660-aux.rs @@ -0,0 +1,11 @@ +#![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/src/test/ui/issues/auxiliary/issue-13507.rs b/src/test/ui/issues/auxiliary/issue-13507.rs new file mode 100644 index 00000000000..c91013043eb --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13507.rs @@ -0,0 +1,87 @@ +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/src/test/ui/issues/auxiliary/issue-13620-1.rs b/src/test/ui/issues/auxiliary/issue-13620-1.rs new file mode 100644 index 00000000000..1442c0cc7aa --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13620-1.rs @@ -0,0 +1,9 @@ +pub struct Foo { + pub foo: extern fn() +} + +extern fn the_foo() {} + +pub const FOO: Foo = Foo { + foo: the_foo +}; diff --git a/src/test/ui/issues/auxiliary/issue-13620-2.rs b/src/test/ui/issues/auxiliary/issue-13620-2.rs new file mode 100644 index 00000000000..7efd24407ba --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13620-2.rs @@ -0,0 +1,3 @@ +extern crate issue_13620_1 as crate1; + +pub static FOO2: crate1::Foo = crate1::FOO; diff --git a/src/test/ui/issues/auxiliary/issue-13872-1.rs b/src/test/ui/issues/auxiliary/issue-13872-1.rs new file mode 100644 index 00000000000..fa9258834c7 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13872-1.rs @@ -0,0 +1 @@ +pub enum A { B } diff --git a/src/test/ui/issues/auxiliary/issue-13872-2.rs b/src/test/ui/issues/auxiliary/issue-13872-2.rs new file mode 100644 index 00000000000..8c64f16e3f9 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13872-2.rs @@ -0,0 +1,3 @@ +extern crate issue_13872_1 as foo; + +pub use foo::A::B; diff --git a/src/test/ui/issues/auxiliary/issue-13872-3.rs b/src/test/ui/issues/auxiliary/issue-13872-3.rs new file mode 100644 index 00000000000..d31d52eb847 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-13872-3.rs @@ -0,0 +1,9 @@ +extern crate issue_13872_2 as bar; + +use bar::B; + +pub fn foo() { + match B { + B => {} + } +} diff --git a/src/test/ui/issues/auxiliary/issue-14344-1.rs b/src/test/ui/issues/auxiliary/issue-14344-1.rs new file mode 100644 index 00000000000..954a1e554da --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-14344-1.rs @@ -0,0 +1,5 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} diff --git a/src/test/ui/issues/auxiliary/issue-14344-2.rs b/src/test/ui/issues/auxiliary/issue-14344-2.rs new file mode 100644 index 00000000000..c47b8c0ea6c --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-14344-2.rs @@ -0,0 +1,3 @@ +extern crate issue_14344_1; + +pub fn bar() {} diff --git a/src/test/ui/issues/auxiliary/issue-14421.rs b/src/test/ui/issues/auxiliary/issue-14421.rs new file mode 100644 index 00000000000..5fe4b24cf17 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-14421.rs @@ -0,0 +1,25 @@ +#![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/src/test/ui/issues/auxiliary/issue-14422.rs b/src/test/ui/issues/auxiliary/issue-14422.rs new file mode 100644 index 00000000000..a6026c1d03f --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-14422.rs @@ -0,0 +1,25 @@ +#![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/src/test/ui/issues/auxiliary/issue-15562.rs b/src/test/ui/issues/auxiliary/issue-15562.rs new file mode 100644 index 00000000000..d5afaaa5622 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-15562.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] + +extern { + pub fn transmute(); +} diff --git a/src/test/ui/issues/auxiliary/issue-16643.rs b/src/test/ui/issues/auxiliary/issue-16643.rs new file mode 100644 index 00000000000..7808e0119f6 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-16643.rs @@ -0,0 +1,19 @@ +#![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/src/test/ui/issues/auxiliary/issue-17662.rs b/src/test/ui/issues/auxiliary/issue-17662.rs new file mode 100644 index 00000000000..75efe110cdf --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-17662.rs @@ -0,0 +1,12 @@ +#![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/src/test/ui/issues/auxiliary/issue-17718-aux.rs b/src/test/ui/issues/auxiliary/issue-17718-aux.rs new file mode 100644 index 00000000000..91abdbff868 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-17718-aux.rs @@ -0,0 +1,10 @@ +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/src/test/ui/issues/auxiliary/issue-18501.rs b/src/test/ui/issues/auxiliary/issue-18501.rs new file mode 100644 index 00000000000..dd914b464fa --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-18501.rs @@ -0,0 +1,17 @@ +#![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/src/test/ui/issues/auxiliary/issue-18514.rs b/src/test/ui/issues/auxiliary/issue-18514.rs new file mode 100644 index 00000000000..20c8e60ee45 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-18514.rs @@ -0,0 +1,17 @@ +#![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/src/test/ui/issues/auxiliary/issue-18711.rs b/src/test/ui/issues/auxiliary/issue-18711.rs new file mode 100644 index 00000000000..5cb1f9c4371 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-18711.rs @@ -0,0 +1,5 @@ +#![crate_type = "rlib"] + +pub fn inner(f: F) -> F { + (move || f)() +} diff --git a/src/test/ui/issues/auxiliary/issue-18913-1.rs b/src/test/ui/issues/auxiliary/issue-18913-1.rs new file mode 100644 index 00000000000..053c5ada5ee --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-18913-1.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![crate_name = "foo"] + +pub fn foo() -> i32 { 0 } diff --git a/src/test/ui/issues/auxiliary/issue-18913-2.rs b/src/test/ui/issues/auxiliary/issue-18913-2.rs new file mode 100644 index 00000000000..54747b45f52 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-18913-2.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![crate_name = "foo"] + +pub fn foo() -> i32 { 1 } diff --git a/src/test/ui/issues/auxiliary/issue-19293.rs b/src/test/ui/issues/auxiliary/issue-19293.rs new file mode 100644 index 00000000000..31359e86559 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-19293.rs @@ -0,0 +1,4 @@ +pub struct Foo (pub isize); +pub enum MyEnum { + Foo(Foo), +} diff --git a/src/test/ui/issues/auxiliary/issue-19340-1.rs b/src/test/ui/issues/auxiliary/issue-19340-1.rs new file mode 100644 index 00000000000..39ee36b8b91 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-19340-1.rs @@ -0,0 +1,3 @@ +pub enum Homura { + Madoka { name: String }, +} diff --git a/src/test/ui/issues/auxiliary/issue-20389.rs b/src/test/ui/issues/auxiliary/issue-20389.rs new file mode 100644 index 00000000000..ae6d44eeb77 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-20389.rs @@ -0,0 +1,4 @@ +pub trait T { + type C; + fn dummy(&self) { } +} diff --git a/src/test/ui/issues/auxiliary/issue-2170-lib.rs b/src/test/ui/issues/auxiliary/issue-2170-lib.rs new file mode 100644 index 00000000000..a99385a834d --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2170-lib.rs @@ -0,0 +1,18 @@ +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/src/test/ui/issues/auxiliary/issue-2316-a.rs b/src/test/ui/issues/auxiliary/issue-2316-a.rs new file mode 100644 index 00000000000..418ddc0b069 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2316-a.rs @@ -0,0 +1,3 @@ +enum cat { + tabby, calico, tortoiseshell +} diff --git a/src/test/ui/issues/auxiliary/issue-2316-b.rs b/src/test/ui/issues/auxiliary/issue-2316-b.rs new file mode 100644 index 00000000000..550c2d6eb22 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2316-b.rs @@ -0,0 +1,11 @@ +#![allow(unused_imports)] + +extern crate issue_2316_a; + +pub mod cloth { + use issue_2316_a::*; + + pub enum fabric { + gingham, flannel, calico + } +} diff --git a/src/test/ui/issues/auxiliary/issue-2380.rs b/src/test/ui/issues/auxiliary/issue-2380.rs new file mode 100644 index 00000000000..9a51a73c9a3 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2380.rs @@ -0,0 +1,15 @@ +#![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/src/test/ui/issues/auxiliary/issue-2414-a.rs b/src/test/ui/issues/auxiliary/issue-2414-a.rs new file mode 100644 index 00000000000..b90ab32ddc4 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2414-a.rs @@ -0,0 +1,12 @@ +#![crate_name="a"] +#![crate_type = "lib"] + +type t1 = usize; + +trait foo { + fn foo(&self); +} + +impl foo for String { + fn foo(&self) {} +} diff --git a/src/test/ui/issues/auxiliary/issue-2414-b.rs b/src/test/ui/issues/auxiliary/issue-2414-b.rs new file mode 100644 index 00000000000..fc018349d80 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2414-b.rs @@ -0,0 +1,4 @@ +#![crate_name="b"] +#![crate_type = "lib"] + +extern crate a; diff --git a/src/test/ui/issues/auxiliary/issue-2472-b.rs b/src/test/ui/issues/auxiliary/issue-2472-b.rs new file mode 100644 index 00000000000..0d151520fe0 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2472-b.rs @@ -0,0 +1,13 @@ +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/src/test/ui/issues/auxiliary/issue-25185-1.rs b/src/test/ui/issues/auxiliary/issue-25185-1.rs new file mode 100644 index 00000000000..77a4787ba94 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-25185-1.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/auxiliary/issue-25185-2.rs b/src/test/ui/issues/auxiliary/issue-25185-2.rs new file mode 100644 index 00000000000..7ce3df255a3 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-25185-2.rs @@ -0,0 +1,3 @@ +extern crate issue_25185_1; + +pub use issue_25185_1::rust_dbg_extern_identity_u32; diff --git a/src/test/ui/issues/auxiliary/issue-2526.rs b/src/test/ui/issues/auxiliary/issue-2526.rs new file mode 100644 index 00000000000..3b27f658cda --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2526.rs @@ -0,0 +1,44 @@ +#![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/src/test/ui/issues/auxiliary/issue-25467.rs b/src/test/ui/issues/auxiliary/issue-25467.rs new file mode 100644 index 00000000000..ca9b3097c83 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-25467.rs @@ -0,0 +1,10 @@ +#![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/src/test/ui/issues/auxiliary/issue-2631-a.rs b/src/test/ui/issues/auxiliary/issue-2631-a.rs new file mode 100644 index 00000000000..1e8211bfaa7 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2631-a.rs @@ -0,0 +1,14 @@ +#![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/src/test/ui/issues/auxiliary/issue-2723-a.rs b/src/test/ui/issues/auxiliary/issue-2723-a.rs new file mode 100644 index 00000000000..661b46d829d --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-2723-a.rs @@ -0,0 +1,3 @@ +pub unsafe fn f(xs: Vec ) { + xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::>(); +} diff --git a/src/test/ui/issues/auxiliary/issue-29485.rs b/src/test/ui/issues/auxiliary/issue-29485.rs new file mode 100644 index 00000000000..1e8891c5120 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-29485.rs @@ -0,0 +1,16 @@ +#![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/src/test/ui/issues/auxiliary/issue-3012-1.rs b/src/test/ui/issues/auxiliary/issue-3012-1.rs new file mode 100644 index 00000000000..509af2a8d7d --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-3012-1.rs @@ -0,0 +1,20 @@ +#![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/src/test/ui/issues/auxiliary/issue-3136-a.rc b/src/test/ui/issues/auxiliary/issue-3136-a.rc new file mode 100644 index 00000000000..cd5fd314505 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-3136-a.rc @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +#[path = "issue-3136-a.rs"] +pub mod issue_3136_a; diff --git a/src/test/ui/issues/auxiliary/issue-3136-a.rs b/src/test/ui/issues/auxiliary/issue-3136-a.rs new file mode 100644 index 00000000000..9bb546ab393 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-3136-a.rs @@ -0,0 +1,14 @@ +trait x { + fn use_x(&self); +} +struct y(()); +impl x for y { + fn use_x(&self) { + struct foo { //~ ERROR quux + i: () + } + fn new_foo(i: ()) -> foo { + foo { i: i } + } + } +} diff --git a/src/test/ui/issues/auxiliary/issue-31702-1.rs b/src/test/ui/issues/auxiliary/issue-31702-1.rs new file mode 100644 index 00000000000..a48d0dc2c64 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-31702-1.rs @@ -0,0 +1,16 @@ +#[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/src/test/ui/issues/auxiliary/issue-31702-2.rs b/src/test/ui/issues/auxiliary/issue-31702-2.rs new file mode 100644 index 00000000000..d360ae0ca7e --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-31702-2.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/auxiliary/issue-34796-aux.rs b/src/test/ui/issues/auxiliary/issue-34796-aux.rs new file mode 100644 index 00000000000..09c69b90329 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-34796-aux.rs @@ -0,0 +1,20 @@ +#![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/src/test/ui/issues/auxiliary/issue-36954.rs b/src/test/ui/issues/auxiliary/issue-36954.rs new file mode 100644 index 00000000000..bc444a3817b --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-36954.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +const fn foo(i: i32) -> i32 { + i +} + +pub const FOO: i32 = foo(1); diff --git a/src/test/ui/issues/auxiliary/issue-38190.rs b/src/test/ui/issues/auxiliary/issue-38190.rs new file mode 100644 index 00000000000..373e646ba2c --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-38190.rs @@ -0,0 +1,2 @@ +#[macro_export] +macro_rules! m { ([$i:item]) => {} } diff --git a/src/test/ui/issues/auxiliary/issue-38226-aux.rs b/src/test/ui/issues/auxiliary/issue-38226-aux.rs new file mode 100644 index 00000000000..f968017199f --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-38226-aux.rs @@ -0,0 +1,23 @@ +#![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/src/test/ui/issues/auxiliary/issue-38715-modern.rs b/src/test/ui/issues/auxiliary/issue-38715-modern.rs new file mode 100644 index 00000000000..15d072957cb --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-38715-modern.rs @@ -0,0 +1,7 @@ +#![allow(duplicate_macro_exports)] + +#[macro_export] +macro_rules! foo_modern { ($i:ident) => {} } + +#[macro_export] +macro_rules! foo_modern { () => {} } diff --git a/src/test/ui/issues/auxiliary/issue-38715.rs b/src/test/ui/issues/auxiliary/issue-38715.rs new file mode 100644 index 00000000000..5c15073f5a5 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-38715.rs @@ -0,0 +1,7 @@ +#![allow(duplicate_macro_exports)] + +#[macro_export] +macro_rules! foo { ($i:ident) => {} } + +#[macro_export] +macro_rules! foo { () => {} } diff --git a/src/test/ui/issues/auxiliary/issue-3979-traits.rs b/src/test/ui/issues/auxiliary/issue-3979-traits.rs new file mode 100644 index 00000000000..5d03a0e9e99 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-3979-traits.rs @@ -0,0 +1,15 @@ +#![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/src/test/ui/issues/auxiliary/issue-39823.rs b/src/test/ui/issues/auxiliary/issue-39823.rs new file mode 100644 index 00000000000..3af9c68f233 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-39823.rs @@ -0,0 +1,7 @@ +#![crate_type="rlib"] + +#[derive(Debug, PartialEq)] +pub struct RemoteC(pub u32); + +#[derive(Debug, PartialEq)] +pub struct RemoteG(pub T); diff --git a/src/test/ui/issues/auxiliary/issue-40469.rs b/src/test/ui/issues/auxiliary/issue-40469.rs new file mode 100644 index 00000000000..4f2f41f2cde --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-40469.rs @@ -0,0 +1 @@ +macro_rules! m { () => { $crate::main(); } } diff --git a/src/test/ui/issues/auxiliary/issue-41053.rs b/src/test/ui/issues/auxiliary/issue-41053.rs new file mode 100644 index 00000000000..ae73c3e780f --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-41053.rs @@ -0,0 +1 @@ +pub struct Test; diff --git a/src/test/ui/issues/auxiliary/issue-41394.rs b/src/test/ui/issues/auxiliary/issue-41394.rs new file mode 100644 index 00000000000..2e650efc714 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-41394.rs @@ -0,0 +1,16 @@ +#![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/src/test/ui/issues/auxiliary/issue-42007-s.rs b/src/test/ui/issues/auxiliary/issue-42007-s.rs new file mode 100644 index 00000000000..95119a589c9 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-42007-s.rs @@ -0,0 +1,4 @@ +#[repr(u8)] +pub enum E { + B = 1 as u8, +} diff --git a/src/test/ui/issues/auxiliary/issue-4208-cc.rs b/src/test/ui/issues/auxiliary/issue-4208-cc.rs new file mode 100644 index 00000000000..7b4c8b01a9e --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-4208-cc.rs @@ -0,0 +1,10 @@ +#![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/src/test/ui/issues/auxiliary/issue-4545.rs b/src/test/ui/issues/auxiliary/issue-4545.rs new file mode 100644 index 00000000000..2f609475075 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-4545.rs @@ -0,0 +1,2 @@ +pub struct S(Option); +pub fn mk() -> S { S(None) } diff --git a/src/test/ui/issues/auxiliary/issue-48984-aux.rs b/src/test/ui/issues/auxiliary/issue-48984-aux.rs new file mode 100644 index 00000000000..7cc888cd4cb --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-48984-aux.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] +#![crate_name = "issue48984aux"] + +pub trait Foo { type Item; } + +pub trait Bar: Foo { } diff --git a/src/test/ui/issues/auxiliary/issue-5518.rs b/src/test/ui/issues/auxiliary/issue-5518.rs new file mode 100644 index 00000000000..bfe96552a5c --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-5518.rs @@ -0,0 +1,4 @@ +trait A<'a, T> { + fn f(&mut self) -> &'a mut T; + fn p() -> T; +} diff --git a/src/test/ui/issues/auxiliary/issue-5521.rs b/src/test/ui/issues/auxiliary/issue-5521.rs new file mode 100644 index 00000000000..c2f81779b35 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-5521.rs @@ -0,0 +1,3 @@ +use std::collections::HashMap; + +pub type map = Box>; diff --git a/src/test/ui/issues/auxiliary/issue-7178.rs b/src/test/ui/issues/auxiliary/issue-7178.rs new file mode 100644 index 00000000000..56ae5139af4 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-7178.rs @@ -0,0 +1,7 @@ +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/src/test/ui/issues/auxiliary/issue-7899.rs b/src/test/ui/issues/auxiliary/issue-7899.rs new file mode 100644 index 00000000000..3af6e871661 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-7899.rs @@ -0,0 +1 @@ +pub struct V2(pub T, pub T); diff --git a/src/test/ui/issues/auxiliary/issue-8044.rs b/src/test/ui/issues/auxiliary/issue-8044.rs new file mode 100644 index 00000000000..2ec25f51cde --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-8044.rs @@ -0,0 +1,15 @@ +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/src/test/ui/issues/auxiliary/issue-8259.rs b/src/test/ui/issues/auxiliary/issue-8259.rs new file mode 100644 index 00000000000..891aee099dc --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-8259.rs @@ -0,0 +1,4 @@ +pub enum Foo<'a> { + A, + B(&'a str), +} diff --git a/src/test/ui/issues/auxiliary/issue-8401.rs b/src/test/ui/issues/auxiliary/issue-8401.rs new file mode 100644 index 00000000000..e35dbbfabfc --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-8401.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/auxiliary/issue-9123.rs b/src/test/ui/issues/auxiliary/issue-9123.rs new file mode 100644 index 00000000000..60af53359e8 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-9123.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] + +pub trait X { + fn x() { + fn f() { } + f(); + } + fn dummy(&self) { } +} diff --git a/src/test/ui/issues/auxiliary/issue-9155.rs b/src/test/ui/issues/auxiliary/issue-9155.rs new file mode 100644 index 00000000000..049a96a655a --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-9155.rs @@ -0,0 +1,7 @@ +pub struct Foo(T); + +impl Foo { + pub fn new(t: T) -> Foo { + Foo(t) + } +} diff --git a/src/test/ui/issues/auxiliary/issue-9188.rs b/src/test/ui/issues/auxiliary/issue-9188.rs new file mode 100644 index 00000000000..3bc5697a1a6 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-9188.rs @@ -0,0 +1,13 @@ +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/src/test/ui/issues/auxiliary/issue-9906.rs b/src/test/ui/issues/auxiliary/issue-9906.rs new file mode 100644 index 00000000000..8a3eea790a2 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-9906.rs @@ -0,0 +1,15 @@ +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/src/test/ui/issues/auxiliary/issue-9968.rs b/src/test/ui/issues/auxiliary/issue-9968.rs new file mode 100644 index 00000000000..8d795b59ea8 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-9968.rs @@ -0,0 +1,22 @@ +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/src/test/ui/issues/issue-10025.rs b/src/test/ui/issues/issue-10025.rs new file mode 100644 index 00000000000..193d7ee891f --- /dev/null +++ b/src/test/ui/issues/issue-10025.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-10028.rs b/src/test/ui/issues/issue-10028.rs new file mode 100644 index 00000000000..1692470e8d1 --- /dev/null +++ b/src/test/ui/issues/issue-10028.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-10031.rs b/src/test/ui/issues/issue-10031.rs new file mode 100644 index 00000000000..136df05c239 --- /dev/null +++ b/src/test/ui/issues/issue-10031.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-10228.rs b/src/test/ui/issues/issue-10228.rs new file mode 100644 index 00000000000..ebf8b436f13 --- /dev/null +++ b/src/test/ui/issues/issue-10228.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-10392.rs b/src/test/ui/issues/issue-10392.rs new file mode 100644 index 00000000000..926fa94800e --- /dev/null +++ b/src/test/ui/issues/issue-10392.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-10436.rs b/src/test/ui/issues/issue-10436.rs new file mode 100644 index 00000000000..a7a20bad517 --- /dev/null +++ b/src/test/ui/issues/issue-10436.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-10626.rs b/src/test/ui/issues/issue-10626.rs new file mode 100644 index 00000000000..78fa8b7c6fb --- /dev/null +++ b/src/test/ui/issues/issue-10626.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-10638.rs b/src/test/ui/issues/issue-10638.rs new file mode 100644 index 00000000000..e359669c00d --- /dev/null +++ b/src/test/ui/issues/issue-10638.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-10682.rs b/src/test/ui/issues/issue-10682.rs new file mode 100644 index 00000000000..afaa90f05ca --- /dev/null +++ b/src/test/ui/issues/issue-10682.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-10683.rs b/src/test/ui/issues/issue-10683.rs new file mode 100644 index 00000000000..dcb221f8c57 --- /dev/null +++ b/src/test/ui/issues/issue-10683.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +static NAME: &'static str = "hello world"; + +fn main() { + match &*NAME.to_ascii_lowercase() { + "foo" => {} + _ => {} + } +} diff --git a/src/test/ui/issues/issue-10718.rs b/src/test/ui/issues/issue-10718.rs new file mode 100644 index 00000000000..a1de0cfe6ca --- /dev/null +++ b/src/test/ui/issues/issue-10718.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(p: F) { + p(); +} + +pub fn main() { + let p = || (); + f(p); +} diff --git a/src/test/ui/issues/issue-10734.rs b/src/test/ui/issues/issue-10734.rs new file mode 100644 index 00000000000..723e6ed22dd --- /dev/null +++ b/src/test/ui/issues/issue-10734.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-10767.rs b/src/test/ui/issues/issue-10767.rs new file mode 100644 index 00000000000..fa10f073b45 --- /dev/null +++ b/src/test/ui/issues/issue-10767.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + fn f() { + }; + let _: Box = box (f as fn()); +} diff --git a/src/test/ui/issues/issue-10802.rs b/src/test/ui/issues/issue-10802.rs new file mode 100644 index 00000000000..f1d6b37a684 --- /dev/null +++ b/src/test/ui/issues/issue-10802.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-10806.rs b/src/test/ui/issues/issue-10806.rs new file mode 100644 index 00000000000..2f1d7bb5aaf --- /dev/null +++ b/src/test/ui/issues/issue-10806.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/issues/issue-11047.rs b/src/test/ui/issues/issue-11047.rs new file mode 100644 index 00000000000..1fb2b5bb3a1 --- /dev/null +++ b/src/test/ui/issues/issue-11047.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-11085.rs b/src/test/ui/issues/issue-11085.rs new file mode 100644 index 00000000000..47c03238b55 --- /dev/null +++ b/src/test/ui/issues/issue-11085.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-1112.rs b/src/test/ui/issues/issue-1112.rs new file mode 100644 index 00000000000..3ba7bb21708 --- /dev/null +++ b/src/test/ui/issues/issue-1112.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/issues/issue-11205.rs b/src/test/ui/issues/issue-11205.rs new file mode 100644 index 00000000000..ce0951eafdd --- /dev/null +++ b/src/test/ui/issues/issue-11205.rs @@ -0,0 +1,85 @@ +// 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/src/test/ui/issues/issue-11224.rs b/src/test/ui/issues/issue-11224.rs new file mode 100644 index 00000000000..e1c1df99aca --- /dev/null +++ b/src/test/ui/issues/issue-11224.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-11224.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11224 as unused; + +pub fn main() {} diff --git a/src/test/ui/issues/issue-11225-1.rs b/src/test/ui/issues/issue-11225-1.rs new file mode 100644 index 00000000000..d1f2ea5e7de --- /dev/null +++ b/src/test/ui/issues/issue-11225-1.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-11225-2.rs b/src/test/ui/issues/issue-11225-2.rs new file mode 100644 index 00000000000..d41c75443f1 --- /dev/null +++ b/src/test/ui/issues/issue-11225-2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-11225-3.rs b/src/test/ui/issues/issue-11225-3.rs new file mode 100644 index 00000000000..e69496baa26 --- /dev/null +++ b/src/test/ui/issues/issue-11225-3.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-11267.rs b/src/test/ui/issues/issue-11267.rs new file mode 100644 index 00000000000..848ed6ac7a8 --- /dev/null +++ b/src/test/ui/issues/issue-11267.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-11382.rs b/src/test/ui/issues/issue-11382.rs new file mode 100644 index 00000000000..42a7a0d04a1 --- /dev/null +++ b/src/test/ui/issues/issue-11382.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + println!("{}", 1.2); +} diff --git a/src/test/ui/issues/issue-11508.rs b/src/test/ui/issues/issue-11508.rs new file mode 100644 index 00000000000..49868b73efa --- /dev/null +++ b/src/test/ui/issues/issue-11508.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-11529.rs b/src/test/ui/issues/issue-11529.rs new file mode 100644 index 00000000000..9a6cc8e9fe8 --- /dev/null +++ b/src/test/ui/issues/issue-11529.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-11552.rs b/src/test/ui/issues/issue-11552.rs new file mode 100644 index 00000000000..bae12375da1 --- /dev/null +++ b/src/test/ui/issues/issue-11552.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-11577.rs b/src/test/ui/issues/issue-11577.rs new file mode 100644 index 00000000000..70177c5ed0d --- /dev/null +++ b/src/test/ui/issues/issue-11577.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-11677.rs b/src/test/ui/issues/issue-11677.rs new file mode 100644 index 00000000000..be18c736f14 --- /dev/null +++ b/src/test/ui/issues/issue-11677.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-11709.rs b/src/test/ui/issues/issue-11709.rs new file mode 100644 index 00000000000..cb5e3dff3b3 --- /dev/null +++ b/src/test/ui/issues/issue-11709.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/issues/issue-11820.rs b/src/test/ui/issues/issue-11820.rs new file mode 100644 index 00000000000..7ffe9652797 --- /dev/null +++ b/src/test/ui/issues/issue-11820.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-11940.rs b/src/test/ui/issues/issue-11940.rs new file mode 100644 index 00000000000..6815c87edd8 --- /dev/null +++ b/src/test/ui/issues/issue-11940.rs @@ -0,0 +1,11 @@ +// run-pass + +const TEST_STR: &'static str = "abcd"; + +fn main() { + let s = "abcd"; + match s { + TEST_STR => (), + _ => unreachable!() + } +} diff --git a/src/test/ui/issues/issue-11958.rs b/src/test/ui/issues/issue-11958.rs new file mode 100644 index 00000000000..8fe8a8c6061 --- /dev/null +++ b/src/test/ui/issues/issue-11958.rs @@ -0,0 +1,10 @@ +// run-pass +#![forbid(warnings)] + +// 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; }); +} diff --git a/src/test/ui/issues/issue-12033.rs b/src/test/ui/issues/issue-12033.rs new file mode 100644 index 00000000000..9dc7573c9d3 --- /dev/null +++ b/src/test/ui/issues/issue-12033.rs @@ -0,0 +1,7 @@ +// run-pass +use std::cell::RefCell; + +fn main() { + let x = RefCell::new(0); + if *x.borrow() == 0 {} else {} +} diff --git a/src/test/ui/issues/issue-12133-1.rs b/src/test/ui/issues/issue-12133-1.rs new file mode 100644 index 00000000000..96ad5abd548 --- /dev/null +++ b/src/test/ui/issues/issue-12133-1.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-12133-2.rs b/src/test/ui/issues/issue-12133-2.rs new file mode 100644 index 00000000000..02fec65c2ed --- /dev/null +++ b/src/test/ui/issues/issue-12133-2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-12133-3.rs b/src/test/ui/issues/issue-12133-3.rs new file mode 100644 index 00000000000..c8aa9bf4649 --- /dev/null +++ b/src/test/ui/issues/issue-12133-3.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-12285.rs b/src/test/ui/issues/issue-12285.rs new file mode 100644 index 00000000000..24ac5d2fbbf --- /dev/null +++ b/src/test/ui/issues/issue-12285.rs @@ -0,0 +1,14 @@ +// run-pass + +struct S; + +fn main() { + match Some(&S) { + Some(&S) => {}, + _x => unreachable!() + } + match Some(&S) { + Some(&S) => {}, + None => unreachable!() + } +} diff --git a/src/test/ui/issues/issue-1257.rs b/src/test/ui/issues/issue-1257.rs new file mode 100644 index 00000000000..de5a6d35925 --- /dev/null +++ b/src/test/ui/issues/issue-1257.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-12582.rs b/src/test/ui/issues/issue-12582.rs new file mode 100644 index 00000000000..f3366704e63 --- /dev/null +++ b/src/test/ui/issues/issue-12582.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-12612.rs b/src/test/ui/issues/issue-12612.rs new file mode 100644 index 00000000000..d254f6941a3 --- /dev/null +++ b/src/test/ui/issues/issue-12612.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-12660.rs b/src/test/ui/issues/issue-12660.rs new file mode 100644 index 00000000000..44c492b43f0 --- /dev/null +++ b/src/test/ui/issues/issue-12660.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-12677.rs b/src/test/ui/issues/issue-12677.rs new file mode 100644 index 00000000000..d0e4c17d4fa --- /dev/null +++ b/src/test/ui/issues/issue-12677.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + let s = "Hello"; + let first = s.bytes(); + let second = first.clone(); + + assert_eq!(first.collect::>(), second.collect::>()) +} diff --git a/src/test/ui/issues/issue-12699.rs b/src/test/ui/issues/issue-12699.rs new file mode 100644 index 00000000000..e26c2d7cde2 --- /dev/null +++ b/src/test/ui/issues/issue-12699.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-12744.rs b/src/test/ui/issues/issue-12744.rs new file mode 100644 index 00000000000..e2756ec970c --- /dev/null +++ b/src/test/ui/issues/issue-12744.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + fn test() -> Box { Box::new(1) } + println!("{:?}", test()) +} diff --git a/src/test/ui/issues/issue-12860.rs b/src/test/ui/issues/issue-12860.rs new file mode 100644 index 00000000000..01b642cdfcc --- /dev/null +++ b/src/test/ui/issues/issue-12860.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/issues/issue-12909.rs b/src/test/ui/issues/issue-12909.rs new file mode 100644 index 00000000000..a68d73a004f --- /dev/null +++ b/src/test/ui/issues/issue-12909.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-13027.rs b/src/test/ui/issues/issue-13027.rs new file mode 100644 index 00000000000..1bab82a543f --- /dev/null +++ b/src/test/ui/issues/issue-13027.rs @@ -0,0 +1,178 @@ +// 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/src/test/ui/issues/issue-13204.rs b/src/test/ui/issues/issue-13204.rs new file mode 100644 index 00000000000..3d6aba8455a --- /dev/null +++ b/src/test/ui/issues/issue-13204.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-13259-windows-tcb-trash.rs b/src/test/ui/issues/issue-13259-windows-tcb-trash.rs new file mode 100644 index 00000000000..740e7780de6 --- /dev/null +++ b/src/test/ui/issues/issue-13259-windows-tcb-trash.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/issues/issue-13264.rs b/src/test/ui/issues/issue-13264.rs new file mode 100644 index 00000000000..691bb63a2fe --- /dev/null +++ b/src/test/ui/issues/issue-13264.rs @@ -0,0 +1,74 @@ +// 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/src/test/ui/issues/issue-13304.rs b/src/test/ui/issues/issue-13304.rs new file mode 100644 index 00000000000..5698536ab5d --- /dev/null +++ b/src/test/ui/issues/issue-13304.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/issues/issue-13323.rs b/src/test/ui/issues/issue-13323.rs new file mode 100644 index 00000000000..26847ee7a08 --- /dev/null +++ b/src/test/ui/issues/issue-13323.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/issues/issue-13434.rs b/src/test/ui/issues/issue-13434.rs new file mode 100644 index 00000000000..1b7d3e20173 --- /dev/null +++ b/src/test/ui/issues/issue-13434.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-13507-2.rs b/src/test/ui/issues/issue-13507-2.rs new file mode 100644 index 00000000000..63f3589c6cc --- /dev/null +++ b/src/test/ui/issues/issue-13507-2.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-13620.rs b/src/test/ui/issues/issue-13620.rs new file mode 100644 index 00000000000..3c3c19df75d --- /dev/null +++ b/src/test/ui/issues/issue-13620.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-13655.rs b/src/test/ui/issues/issue-13655.rs new file mode 100644 index 00000000000..6dd1847995f --- /dev/null +++ b/src/test/ui/issues/issue-13655.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-13665.rs b/src/test/ui/issues/issue-13665.rs new file mode 100644 index 00000000000..a3843c65034 --- /dev/null +++ b/src/test/ui/issues/issue-13665.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-13763.rs b/src/test/ui/issues/issue-13763.rs new file mode 100644 index 00000000000..dd5f6dbc9dc --- /dev/null +++ b/src/test/ui/issues/issue-13763.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-13808.rs b/src/test/ui/issues/issue-13808.rs new file mode 100644 index 00000000000..9f9db067bf4 --- /dev/null +++ b/src/test/ui/issues/issue-13808.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-13867.rs b/src/test/ui/issues/issue-13867.rs new file mode 100644 index 00000000000..e66368f9ba8 --- /dev/null +++ b/src/test/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/src/test/ui/issues/issue-13872.rs b/src/test/ui/issues/issue-13872.rs new file mode 100644 index 00000000000..aade6b8367c --- /dev/null +++ b/src/test/ui/issues/issue-13872.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-13902.rs b/src/test/ui/issues/issue-13902.rs new file mode 100644 index 00000000000..1afde0ebe85 --- /dev/null +++ b/src/test/ui/issues/issue-13902.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-14229.rs b/src/test/ui/issues/issue-14229.rs new file mode 100644 index 00000000000..477a2c65053 --- /dev/null +++ b/src/test/ui/issues/issue-14229.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-14308.rs b/src/test/ui/issues/issue-14308.rs new file mode 100644 index 00000000000..e067bcdf34a --- /dev/null +++ b/src/test/ui/issues/issue-14308.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-14344.rs b/src/test/ui/issues/issue-14344.rs new file mode 100644 index 00000000000..33b1df827d3 --- /dev/null +++ b/src/test/ui/issues/issue-14344.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-14382.rs b/src/test/ui/issues/issue-14382.rs new file mode 100644 index 00000000000..671e7a22667 --- /dev/null +++ b/src/test/ui/issues/issue-14382.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-14393.rs b/src/test/ui/issues/issue-14393.rs new file mode 100644 index 00000000000..df635407af6 --- /dev/null +++ b/src/test/ui/issues/issue-14393.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + match ("", 1_usize) { + (_, 42_usize) => (), + ("", _) => (), + _ => () + } +} diff --git a/src/test/ui/issues/issue-14399.rs b/src/test/ui/issues/issue-14399.rs new file mode 100644 index 00000000000..6bf8a589959 --- /dev/null +++ b/src/test/ui/issues/issue-14399.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-14421.rs b/src/test/ui/issues/issue-14421.rs new file mode 100644 index 00000000000..c59bd87065f --- /dev/null +++ b/src/test/ui/issues/issue-14421.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-14422.rs b/src/test/ui/issues/issue-14422.rs new file mode 100644 index 00000000000..b9e2065d014 --- /dev/null +++ b/src/test/ui/issues/issue-14422.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-14456.rs b/src/test/ui/issues/issue-14456.rs new file mode 100644 index 00000000000..164d7ef8af2 --- /dev/null +++ b/src/test/ui/issues/issue-14456.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/issues/issue-1451.rs b/src/test/ui/issues/issue-1451.rs new file mode 100644 index 00000000000..ad8928b2043 --- /dev/null +++ b/src/test/ui/issues/issue-1451.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-14589.rs b/src/test/ui/issues/issue-14589.rs new file mode 100644 index 00000000000..5d8aab2ce74 --- /dev/null +++ b/src/test/ui/issues/issue-14589.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-1460.rs b/src/test/ui/issues/issue-1460.rs new file mode 100644 index 00000000000..143a0387e21 --- /dev/null +++ b/src/test/ui/issues/issue-1460.rs @@ -0,0 +1,7 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +pub fn main() { + {|i: u32| if 1 == i { }}; +} diff --git a/src/test/ui/issues/issue-14821.rs b/src/test/ui/issues/issue-14821.rs new file mode 100644 index 00000000000..00b2e3607fc --- /dev/null +++ b/src/test/ui/issues/issue-14821.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-14865.rs b/src/test/ui/issues/issue-14865.rs new file mode 100644 index 00000000000..56e78e78f18 --- /dev/null +++ b/src/test/ui/issues/issue-14865.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-14875.rs b/src/test/ui/issues/issue-14875.rs new file mode 100644 index 00000000000..a2fd7962458 --- /dev/null +++ b/src/test/ui/issues/issue-14875.rs @@ -0,0 +1,35 @@ +// run-pass +// ignore-wasm32-bare always compiled as panic=abort right now + +// 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/src/test/ui/issues/issue-14919.rs b/src/test/ui/issues/issue-14919.rs new file mode 100644 index 00000000000..94361543354 --- /dev/null +++ b/src/test/ui/issues/issue-14919.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/issues/issue-14940.rs b/src/test/ui/issues/issue-14940.rs new file mode 100644 index 00000000000..785ad6a2c49 --- /dev/null +++ b/src/test/ui/issues/issue-14940.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-14958.rs b/src/test/ui/issues/issue-14958.rs new file mode 100644 index 00000000000..a12564ca9c0 --- /dev/null +++ b/src/test/ui/issues/issue-14958.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-15043.rs b/src/test/ui/issues/issue-15043.rs new file mode 100644 index 00000000000..53748be8a02 --- /dev/null +++ b/src/test/ui/issues/issue-15043.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-15063.rs b/src/test/ui/issues/issue-15063.rs new file mode 100644 index 00000000000..4082675129d --- /dev/null +++ b/src/test/ui/issues/issue-15063.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs new file mode 100644 index 00000000000..4558118a809 --- /dev/null +++ b/src/test/ui/issues/issue-15080.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs new file mode 100644 index 00000000000..3a03a52c324 --- /dev/null +++ b/src/test/ui/issues/issue-15104.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/issues/issue-15155.rs b/src/test/ui/issues/issue-15155.rs new file mode 100644 index 00000000000..7b137b4af56 --- /dev/null +++ b/src/test/ui/issues/issue-15155.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-15189.rs b/src/test/ui/issues/issue-15189.rs new file mode 100644 index 00000000000..a9c884bdcfd --- /dev/null +++ b/src/test/ui/issues/issue-15189.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-15221.rs b/src/test/ui/issues/issue-15221.rs new file mode 100644 index 00000000000..4b8319a8304 --- /dev/null +++ b/src/test/ui/issues/issue-15221.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-15444.rs b/src/test/ui/issues/issue-15444.rs new file mode 100644 index 00000000000..e94afee9634 --- /dev/null +++ b/src/test/ui/issues/issue-15444.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-15487.rs b/src/test/ui/issues/issue-15487.rs new file mode 100644 index 00000000000..98714cba0e4 --- /dev/null +++ b/src/test/ui/issues/issue-15487.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_attributes)] +// ignore-windows +// ignore-wasm32-bare no libs to link + +#![feature(link_args)] + +#[link_args="-lc -lm"] +#[link_args=" -lc"] +#[link_args="-lc "] +extern {} + +fn main() {} diff --git a/src/test/ui/issues/issue-15523-big.rs b/src/test/ui/issues/issue-15523-big.rs new file mode 100644 index 00000000000..05414f1db72 --- /dev/null +++ b/src/test/ui/issues/issue-15523-big.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/issues/issue-15523.rs b/src/test/ui/issues/issue-15523.rs new file mode 100644 index 00000000000..220a34b9b0f --- /dev/null +++ b/src/test/ui/issues/issue-15523.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/issues/issue-15562.rs b/src/test/ui/issues/issue-15562.rs new file mode 100644 index 00000000000..b37ba81e291 --- /dev/null +++ b/src/test/ui/issues/issue-15562.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-15571.rs b/src/test/ui/issues/issue-15571.rs new file mode 100644 index 00000000000..5381d65232f --- /dev/null +++ b/src/test/ui/issues/issue-15571.rs @@ -0,0 +1,58 @@ +// 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/src/test/ui/issues/issue-15673.rs b/src/test/ui/issues/issue-15673.rs new file mode 100644 index 00000000000..a8733d7f157 --- /dev/null +++ b/src/test/ui/issues/issue-15673.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-15689-1.rs b/src/test/ui/issues/issue-15689-1.rs new file mode 100644 index 00000000000..d143926b281 --- /dev/null +++ b/src/test/ui/issues/issue-15689-1.rs @@ -0,0 +1,10 @@ +// run-pass + +#[derive(PartialEq, Debug)] +enum Test<'a> { + Slice(&'a isize) +} + +fn main() { + assert_eq!(Test::Slice(&1), Test::Slice(&1)) +} diff --git a/src/test/ui/issues/issue-15730.rs b/src/test/ui/issues/issue-15730.rs new file mode 100644 index 00000000000..dacffd154fc --- /dev/null +++ b/src/test/ui/issues/issue-15730.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-15734.rs b/src/test/ui/issues/issue-15734.rs new file mode 100644 index 00000000000..be582060601 --- /dev/null +++ b/src/test/ui/issues/issue-15734.rs @@ -0,0 +1,58 @@ +// 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/src/test/ui/issues/issue-15763.rs b/src/test/ui/issues/issue-15763.rs new file mode 100644 index 00000000000..9ceffff2e38 --- /dev/null +++ b/src/test/ui/issues/issue-15763.rs @@ -0,0 +1,89 @@ +// 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/src/test/ui/issues/issue-15774.rs b/src/test/ui/issues/issue-15774.rs new file mode 100644 index 00000000000..ed2235758b9 --- /dev/null +++ b/src/test/ui/issues/issue-15774.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-15793.rs b/src/test/ui/issues/issue-15793.rs new file mode 100644 index 00000000000..769012b1ba7 --- /dev/null +++ b/src/test/ui/issues/issue-15793.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-15858.rs b/src/test/ui/issues/issue-15858.rs new file mode 100644 index 00000000000..41d2f13952a --- /dev/null +++ b/src/test/ui/issues/issue-15858.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs b/src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs new file mode 100644 index 00000000000..dee7f25d7bb --- /dev/null +++ b/src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/issues/issue-16151.rs b/src/test/ui/issues/issue-16151.rs new file mode 100644 index 00000000000..48a14b2af7c --- /dev/null +++ b/src/test/ui/issues/issue-16151.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-16256.rs b/src/test/ui/issues/issue-16256.rs new file mode 100644 index 00000000000..e566eede8d2 --- /dev/null +++ b/src/test/ui/issues/issue-16256.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let mut buf = Vec::new(); + |c: u8| buf.push(c); +} diff --git a/src/test/ui/issues/issue-16272.rs b/src/test/ui/issues/issue-16272.rs new file mode 100644 index 00000000000..3ba2483f430 --- /dev/null +++ b/src/test/ui/issues/issue-16272.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-16278.rs b/src/test/ui/issues/issue-16278.rs new file mode 100644 index 00000000000..2f47b694ae9 --- /dev/null +++ b/src/test/ui/issues/issue-16278.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-16441.rs b/src/test/ui/issues/issue-16441.rs new file mode 100644 index 00000000000..bae3813f9da --- /dev/null +++ b/src/test/ui/issues/issue-16441.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Empty; + +// This used to cause an ICE +extern "C" fn ice(_a: Empty) {} + +fn main() { +} diff --git a/src/test/ui/issues/issue-16452.rs b/src/test/ui/issues/issue-16452.rs new file mode 100644 index 00000000000..faf9edd3b26 --- /dev/null +++ b/src/test/ui/issues/issue-16452.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn main() { + if true { return } + match () { + () => { static MAGIC: usize = 0; } + } +} diff --git a/src/test/ui/issues/issue-16492.rs b/src/test/ui/issues/issue-16492.rs new file mode 100644 index 00000000000..7fa808237bf --- /dev/null +++ b/src/test/ui/issues/issue-16492.rs @@ -0,0 +1,67 @@ +// 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/src/test/ui/issues/issue-16530.rs b/src/test/ui/issues/issue-16530.rs new file mode 100644 index 00000000000..22a6ef7fa09 --- /dev/null +++ b/src/test/ui/issues/issue-16530.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(deprecated)] + +use std::hash::{SipHasher, Hasher, Hash}; + +#[derive(Hash)] +struct Empty; + +pub fn main() { + let mut s1 = SipHasher::new_with_keys(0, 0); + Empty.hash(&mut s1); + let mut s2 = SipHasher::new_with_keys(0, 0); + Empty.hash(&mut s2); + assert_eq!(s1.finish(), s2.finish()); +} diff --git a/src/test/ui/issues/issue-16560.rs b/src/test/ui/issues/issue-16560.rs new file mode 100644 index 00000000000..d5fffc7ef9b --- /dev/null +++ b/src/test/ui/issues/issue-16560.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-16597-empty.rs b/src/test/ui/issues/issue-16597-empty.rs new file mode 100644 index 00000000000..2bdd08575c4 --- /dev/null +++ b/src/test/ui/issues/issue-16597-empty.rs @@ -0,0 +1,5 @@ +// 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/src/test/ui/issues/issue-16597.rs b/src/test/ui/issues/issue-16597.rs new file mode 100644 index 00000000000..35769bfc117 --- /dev/null +++ b/src/test/ui/issues/issue-16597.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_imports)] +// compile-flags:--test + +mod tests { + use super::*; + + #[test] + pub fn test(){} +} diff --git a/src/test/ui/issues/issue-1660.rs b/src/test/ui/issues/issue-1660.rs new file mode 100644 index 00000000000..aa60a8d8a96 --- /dev/null +++ b/src/test/ui/issues/issue-1660.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 + +pub fn main() { + static _x: isize = 1<<2; +} diff --git a/src/test/ui/issues/issue-16602-1.rs b/src/test/ui/issues/issue-16602-1.rs new file mode 100644 index 00000000000..dd64ee75b34 --- /dev/null +++ b/src/test/ui/issues/issue-16602-1.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + let mut t = [1; 2]; + t = [t[1] * 2, t[0] * 2]; + assert_eq!(&t[..], &[2, 2]); +} diff --git a/src/test/ui/issues/issue-16602-2.rs b/src/test/ui/issues/issue-16602-2.rs new file mode 100644 index 00000000000..6364630ffa9 --- /dev/null +++ b/src/test/ui/issues/issue-16602-2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-16602-3.rs b/src/test/ui/issues/issue-16602-3.rs new file mode 100644 index 00000000000..dbfeef053da --- /dev/null +++ b/src/test/ui/issues/issue-16602-3.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-16643.rs b/src/test/ui/issues/issue-16643.rs new file mode 100644 index 00000000000..c74a554af2e --- /dev/null +++ b/src/test/ui/issues/issue-16643.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-16648.rs b/src/test/ui/issues/issue-16648.rs new file mode 100644 index 00000000000..539f015fa28 --- /dev/null +++ b/src/test/ui/issues/issue-16648.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-16671.rs b/src/test/ui/issues/issue-16671.rs new file mode 100644 index 00000000000..eff8e275bb5 --- /dev/null +++ b/src/test/ui/issues/issue-16671.rs @@ -0,0 +1,12 @@ +// run-pass + +#![deny(warnings)] + +fn foo(_f: F) { } + +fn main() { + let mut var = Vec::new(); + foo(move|| { + var.push(1); + }); +} diff --git a/src/test/ui/issues/issue-16739.rs b/src/test/ui/issues/issue-16739.rs new file mode 100644 index 00000000000..54ad8fd076e --- /dev/null +++ b/src/test/ui/issues/issue-16739.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/issues/issue-16745.rs b/src/test/ui/issues/issue-16745.rs new file mode 100644 index 00000000000..e9137df0f1e --- /dev/null +++ b/src/test/ui/issues/issue-16745.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-16774.rs b/src/test/ui/issues/issue-16774.rs new file mode 100644 index 00000000000..9e9b84034db --- /dev/null +++ b/src/test/ui/issues/issue-16774.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-16783.rs b/src/test/ui/issues/issue-16783.rs new file mode 100644 index 00000000000..4af4031d278 --- /dev/null +++ b/src/test/ui/issues/issue-16783.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = [1, 2, 3]; + let y = x; +} diff --git a/src/test/ui/issues/issue-16819.rs b/src/test/ui/issues/issue-16819.rs new file mode 100644 index 00000000000..cc0200904e5 --- /dev/null +++ b/src/test/ui/issues/issue-16819.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-1696.rs b/src/test/ui/issues/issue-1696.rs new file mode 100644 index 00000000000..b5d77df3a18 --- /dev/null +++ b/src/test/ui/issues/issue-1696.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-1701.rs b/src/test/ui/issues/issue-1701.rs new file mode 100644 index 00000000000..bae32a77765 --- /dev/null +++ b/src/test/ui/issues/issue-1701.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-17068.rs b/src/test/ui/issues/issue-17068.rs new file mode 100644 index 00000000000..fe2c1a34bb4 --- /dev/null +++ b/src/test/ui/issues/issue-17068.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-17074.rs b/src/test/ui/issues/issue-17074.rs new file mode 100644 index 00000000000..0ed81132ec6 --- /dev/null +++ b/src/test/ui/issues/issue-17074.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-17170.rs b/src/test/ui/issues/issue-17170.rs new file mode 100644 index 00000000000..8d70dacdc90 --- /dev/null +++ b/src/test/ui/issues/issue-17170.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-17216.rs b/src/test/ui/issues/issue-17216.rs new file mode 100644 index 00000000000..05baa1bffdd --- /dev/null +++ b/src/test/ui/issues/issue-17216.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-17233.rs b/src/test/ui/issues/issue-17233.rs new file mode 100644 index 00000000000..54a12fdf8e8 --- /dev/null +++ b/src/test/ui/issues/issue-17233.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-17302.rs b/src/test/ui/issues/issue-17302.rs new file mode 100644 index 00000000000..cf7a2f1b063 --- /dev/null +++ b/src/test/ui/issues/issue-17302.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-17322.rs b/src/test/ui/issues/issue-17322.rs new file mode 100644 index 00000000000..20a8d136124 --- /dev/null +++ b/src/test/ui/issues/issue-17322.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-17351.rs b/src/test/ui/issues/issue-17351.rs new file mode 100644 index 00000000000..62f6bcf15e3 --- /dev/null +++ b/src/test/ui/issues/issue-17351.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-17361.rs b/src/test/ui/issues/issue-17361.rs new file mode 100644 index 00000000000..e97fc3afd1c --- /dev/null +++ b/src/test/ui/issues/issue-17361.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-17503.rs b/src/test/ui/issues/issue-17503.rs new file mode 100644 index 00000000000..9a92c06e159 --- /dev/null +++ b/src/test/ui/issues/issue-17503.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-17662.rs b/src/test/ui/issues/issue-17662.rs new file mode 100644 index 00000000000..a2683808b52 --- /dev/null +++ b/src/test/ui/issues/issue-17662.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-17718-borrow-interior.rs b/src/test/ui/issues/issue-17718-borrow-interior.rs new file mode 100644 index 00000000000..5861f218689 --- /dev/null +++ b/src/test/ui/issues/issue-17718-borrow-interior.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-17718-parse-const.rs b/src/test/ui/issues/issue-17718-parse-const.rs new file mode 100644 index 00000000000..d5a5f445d5b --- /dev/null +++ b/src/test/ui/issues/issue-17718-parse-const.rs @@ -0,0 +1,7 @@ +// run-pass + +const FOO: usize = 3; + +fn main() { + assert_eq!(FOO, 3); +} diff --git a/src/test/ui/issues/issue-17718-static-unsafe-interior.rs b/src/test/ui/issues/issue-17718-static-unsafe-interior.rs new file mode 100644 index 00000000000..65a8713ba05 --- /dev/null +++ b/src/test/ui/issues/issue-17718-static-unsafe-interior.rs @@ -0,0 +1,52 @@ +// 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/src/test/ui/issues/issue-17718.rs b/src/test/ui/issues/issue-17718.rs new file mode 100644 index 00000000000..c6341d80844 --- /dev/null +++ b/src/test/ui/issues/issue-17718.rs @@ -0,0 +1,75 @@ +// 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/src/test/ui/issues/issue-17734.rs b/src/test/ui/issues/issue-17734.rs new file mode 100644 index 00000000000..ba8d6c21ca8 --- /dev/null +++ b/src/test/ui/issues/issue-17734.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-17756.rs b/src/test/ui/issues/issue-17756.rs new file mode 100644 index 00000000000..1835b177ff3 --- /dev/null +++ b/src/test/ui/issues/issue-17756.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-17771.rs b/src/test/ui/issues/issue-17771.rs new file mode 100644 index 00000000000..2f6464668c2 --- /dev/null +++ b/src/test/ui/issues/issue-17771.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-17816.rs b/src/test/ui/issues/issue-17816.rs new file mode 100644 index 00000000000..7ca47d50335 --- /dev/null +++ b/src/test/ui/issues/issue-17816.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs new file mode 100644 index 00000000000..af22b1ad8f0 --- /dev/null +++ b/src/test/ui/issues/issue-17877.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/issues/issue-17897.rs b/src/test/ui/issues/issue-17897.rs new file mode 100644 index 00000000000..6873c7ccb7f --- /dev/null +++ b/src/test/ui/issues/issue-17897.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-18060.rs b/src/test/ui/issues/issue-18060.rs new file mode 100644 index 00000000000..b5f3d0f74bc --- /dev/null +++ b/src/test/ui/issues/issue-18060.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-18075.rs b/src/test/ui/issues/issue-18075.rs new file mode 100644 index 00000000000..ee6845c1278 --- /dev/null +++ b/src/test/ui/issues/issue-18075.rs @@ -0,0 +1,7 @@ +// run-pass +// exec-env:RUSTC_LOG=rustc::middle=debug + +fn main() { + let b = 1isize; + println!("{}", b); +} diff --git a/src/test/ui/issues/issue-18110.rs b/src/test/ui/issues/issue-18110.rs new file mode 100644 index 00000000000..41c29e77da5 --- /dev/null +++ b/src/test/ui/issues/issue-18110.rs @@ -0,0 +1,7 @@ +// run-pass +#![allow(unreachable_code)] +// pretty-expanded FIXME #23616 + +fn main() { + ({return},); +} diff --git a/src/test/ui/issues/issue-18173.rs b/src/test/ui/issues/issue-18173.rs new file mode 100644 index 00000000000..11468040ee5 --- /dev/null +++ b/src/test/ui/issues/issue-18173.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-18232.rs b/src/test/ui/issues/issue-18232.rs new file mode 100644 index 00000000000..7e6f6ef0f39 --- /dev/null +++ b/src/test/ui/issues/issue-18232.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-18352.rs b/src/test/ui/issues/issue-18352.rs new file mode 100644 index 00000000000..5d93ed0646c --- /dev/null +++ b/src/test/ui/issues/issue-18352.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-18353.rs b/src/test/ui/issues/issue-18353.rs new file mode 100644 index 00000000000..3d15c9980c3 --- /dev/null +++ b/src/test/ui/issues/issue-18353.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-18412.rs b/src/test/ui/issues/issue-18412.rs new file mode 100644 index 00000000000..fe1cfb3dffa --- /dev/null +++ b/src/test/ui/issues/issue-18412.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-18425.rs b/src/test/ui/issues/issue-18425.rs new file mode 100644 index 00000000000..354c14a756a --- /dev/null +++ b/src/test/ui/issues/issue-18425.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-18464.rs b/src/test/ui/issues/issue-18464.rs new file mode 100644 index 00000000000..14d2d0a6c8d --- /dev/null +++ b/src/test/ui/issues/issue-18464.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-18501.rs b/src/test/ui/issues/issue-18501.rs new file mode 100644 index 00000000000..0ca23074c55 --- /dev/null +++ b/src/test/ui/issues/issue-18501.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-18514.rs b/src/test/ui/issues/issue-18514.rs new file mode 100644 index 00000000000..48e7f07418f --- /dev/null +++ b/src/test/ui/issues/issue-18514.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-18539.rs b/src/test/ui/issues/issue-18539.rs new file mode 100644 index 00000000000..745df26e320 --- /dev/null +++ b/src/test/ui/issues/issue-18539.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-18652.rs b/src/test/ui/issues/issue-18652.rs new file mode 100644 index 00000000000..59aa0156842 --- /dev/null +++ b/src/test/ui/issues/issue-18652.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-18655.rs b/src/test/ui/issues/issue-18655.rs new file mode 100644 index 00000000000..3d18542acdc --- /dev/null +++ b/src/test/ui/issues/issue-18655.rs @@ -0,0 +1,22 @@ +// run-pass +trait Factory { + type Product; + fn create(&self) -> ::Product; +} + +impl Factory for f64 { + type Product = f64; + fn create(&self) -> f64 { *self * *self } +} + +impl Factory for (A, B) { + type Product = (::Product, ::Product); + fn create(&self) -> (::Product, ::Product) { + let (ref a, ref b) = *self; + (a.create(), b.create()) + } +} + +fn main() { + assert_eq!((16., 25.), (4., 5.).create()); +} diff --git a/src/test/ui/issues/issue-18661.rs b/src/test/ui/issues/issue-18661.rs new file mode 100644 index 00000000000..e2427243235 --- /dev/null +++ b/src/test/ui/issues/issue-18661.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-18685.rs b/src/test/ui/issues/issue-18685.rs new file mode 100644 index 00000000000..bfe24b663f6 --- /dev/null +++ b/src/test/ui/issues/issue-18685.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-18711.rs b/src/test/ui/issues/issue-18711.rs new file mode 100644 index 00000000000..43584187752 --- /dev/null +++ b/src/test/ui/issues/issue-18711.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-18767.rs b/src/test/ui/issues/issue-18767.rs new file mode 100644 index 00000000000..2a5721b7295 --- /dev/null +++ b/src/test/ui/issues/issue-18767.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-18804/auxiliary/lib.rs b/src/test/ui/issues/issue-18804/auxiliary/lib.rs new file mode 100644 index 00000000000..ae27dd520e9 --- /dev/null +++ b/src/test/ui/issues/issue-18804/auxiliary/lib.rs @@ -0,0 +1,10 @@ +#![crate_type = "rlib"] +#![feature(linkage)] + +pub fn foo() -> *const() { + extern { + #[linkage = "extern_weak"] + static FOO: *const(); + } + unsafe { FOO } +} diff --git a/src/test/ui/issues/issue-18804/main.rs b/src/test/ui/issues/issue-18804/main.rs new file mode 100644 index 00000000000..c36048ea545 --- /dev/null +++ b/src/test/ui/issues/issue-18804/main.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-18845.rs b/src/test/ui/issues/issue-18845.rs new file mode 100644 index 00000000000..83fab4b5e8f --- /dev/null +++ b/src/test/ui/issues/issue-18845.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-18859.rs b/src/test/ui/issues/issue-18859.rs new file mode 100644 index 00000000000..c4575bce925 --- /dev/null +++ b/src/test/ui/issues/issue-18859.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-18913.rs b/src/test/ui/issues/issue-18913.rs new file mode 100644 index 00000000000..27fae6d7757 --- /dev/null +++ b/src/test/ui/issues/issue-18913.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-18937-1.rs b/src/test/ui/issues/issue-18937-1.rs new file mode 100644 index 00000000000..57e56d832c6 --- /dev/null +++ b/src/test/ui/issues/issue-18937-1.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-18952.rs b/src/test/ui/issues/issue-18952.rs new file mode 100644 index 00000000000..56378b59e36 --- /dev/null +++ b/src/test/ui/issues/issue-18952.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/issues/issue-19001.rs b/src/test/ui/issues/issue-19001.rs new file mode 100644 index 00000000000..76c380c2fc9 --- /dev/null +++ b/src/test/ui/issues/issue-19001.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-19127.rs b/src/test/ui/issues/issue-19127.rs new file mode 100644 index 00000000000..c847ac9e435 --- /dev/null +++ b/src/test/ui/issues/issue-19127.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-19135.rs b/src/test/ui/issues/issue-19135.rs new file mode 100644 index 00000000000..84540a3ff5f --- /dev/null +++ b/src/test/ui/issues/issue-19135.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-19244.rs b/src/test/ui/issues/issue-19244.rs new file mode 100644 index 00000000000..44d9748fd2a --- /dev/null +++ b/src/test/ui/issues/issue-19244.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-19293.rs b/src/test/ui/issues/issue-19293.rs new file mode 100644 index 00000000000..b6e9e3d065a --- /dev/null +++ b/src/test/ui/issues/issue-19293.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-19340-1.rs b/src/test/ui/issues/issue-19340-1.rs new file mode 100644 index 00000000000..e3cc2daae9b --- /dev/null +++ b/src/test/ui/issues/issue-19340-1.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-19340-2.rs b/src/test/ui/issues/issue-19340-2.rs new file mode 100644 index 00000000000..a222e9e4621 --- /dev/null +++ b/src/test/ui/issues/issue-19340-2.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-19358.rs b/src/test/ui/issues/issue-19358.rs new file mode 100644 index 00000000000..f66e0a1c078 --- /dev/null +++ b/src/test/ui/issues/issue-19358.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-19367.rs b/src/test/ui/issues/issue-19367.rs new file mode 100644 index 00000000000..0699533e72b --- /dev/null +++ b/src/test/ui/issues/issue-19367.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-19499.rs b/src/test/ui/issues/issue-19499.rs new file mode 100644 index 00000000000..d09056ce3de --- /dev/null +++ b/src/test/ui/issues/issue-19499.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-1974.rs b/src/test/ui/issues/issue-1974.rs new file mode 100644 index 00000000000..74a54a6029e --- /dev/null +++ b/src/test/ui/issues/issue-1974.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-19811-escape-unicode.rs b/src/test/ui/issues/issue-19811-escape-unicode.rs new file mode 100644 index 00000000000..a2c50bc022d --- /dev/null +++ b/src/test/ui/issues/issue-19811-escape-unicode.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-20055-box-trait.rs b/src/test/ui/issues/issue-20055-box-trait.rs new file mode 100644 index 00000000000..772cd9d7eda --- /dev/null +++ b/src/test/ui/issues/issue-20055-box-trait.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/issues/issue-20055-box-unsized-array.rs b/src/test/ui/issues/issue-20055-box-unsized-array.rs new file mode 100644 index 00000000000..1246c80651f --- /dev/null +++ b/src/test/ui/issues/issue-20055-box-unsized-array.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-20174.rs b/src/test/ui/issues/issue-20174.rs new file mode 100644 index 00000000000..4ed5a97c172 --- /dev/null +++ b/src/test/ui/issues/issue-20174.rs @@ -0,0 +1,7 @@ +// run-pass +struct GradFn usize>(F); + +fn main() { + let GradFn(x_squared) : GradFn<_> = GradFn(|| -> usize { 2 }); + let _ = x_squared(); +} diff --git a/src/test/ui/issues/issue-20343.rs b/src/test/ui/issues/issue-20343.rs new file mode 100644 index 00000000000..000b6398442 --- /dev/null +++ b/src/test/ui/issues/issue-20343.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-20389.rs b/src/test/ui/issues/issue-20389.rs new file mode 100644 index 00000000000..9bc3efcc1c4 --- /dev/null +++ b/src/test/ui/issues/issue-20389.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-20427.rs b/src/test/ui/issues/issue-20427.rs new file mode 100644 index 00000000000..fa2ea6cf592 --- /dev/null +++ b/src/test/ui/issues/issue-20427.rs @@ -0,0 +1,88 @@ +// 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/src/test/ui/issues/issue-20544.rs b/src/test/ui/issues/issue-20544.rs new file mode 100644 index 00000000000..0f4d314f166 --- /dev/null +++ b/src/test/ui/issues/issue-20544.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-20575.rs b/src/test/ui/issues/issue-20575.rs new file mode 100644 index 00000000000..0ca67d9dc71 --- /dev/null +++ b/src/test/ui/issues/issue-20575.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-20616.rs b/src/test/ui/issues/issue-20616.rs new file mode 100644 index 00000000000..6c24d437272 --- /dev/null +++ b/src/test/ui/issues/issue-20616.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/issues/issue-2063.rs b/src/test/ui/issues/issue-2063.rs new file mode 100644 index 00000000000..9dbac6ccee1 --- /dev/null +++ b/src/test/ui/issues/issue-2063.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-20676.rs b/src/test/ui/issues/issue-20676.rs new file mode 100644 index 00000000000..2bc5034960a --- /dev/null +++ b/src/test/ui/issues/issue-20676.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-2074.rs b/src/test/ui/issues/issue-2074.rs new file mode 100644 index 00000000000..bd5f015cca0 --- /dev/null +++ b/src/test/ui/issues/issue-2074.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-20803.rs b/src/test/ui/issues/issue-20803.rs new file mode 100644 index 00000000000..f657cf6cdd7 --- /dev/null +++ b/src/test/ui/issues/issue-20803.rs @@ -0,0 +1,10 @@ +// run-pass +use std::ops::Add; + +fn foo(x: T) -> >::Output where i32: Add { + 42i32 + x +} + +fn main() { + println!("{}", foo(0i32)); +} diff --git a/src/test/ui/issues/issue-20823.rs b/src/test/ui/issues/issue-20823.rs new file mode 100644 index 00000000000..9e209d5d33a --- /dev/null +++ b/src/test/ui/issues/issue-20823.rs @@ -0,0 +1,5 @@ +// run-pass +// compile-flags: --test + +#[test] +pub fn foo() {} diff --git a/src/test/ui/issues/issue-20847.rs b/src/test/ui/issues/issue-20847.rs new file mode 100644 index 00000000000..0cd7edf89db --- /dev/null +++ b/src/test/ui/issues/issue-20847.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-20953.rs b/src/test/ui/issues/issue-20953.rs new file mode 100644 index 00000000000..4ec7e3195eb --- /dev/null +++ b/src/test/ui/issues/issue-20953.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-21033.rs b/src/test/ui/issues/issue-21033.rs new file mode 100644 index 00000000000..86cc7707e50 --- /dev/null +++ b/src/test/ui/issues/issue-21033.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/issues/issue-21058.rs b/src/test/ui/issues/issue-21058.rs new file mode 100644 index 00000000000..6facf0b2dd5 --- /dev/null +++ b/src/test/ui/issues/issue-21058.rs @@ -0,0 +1,64 @@ +// 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/src/test/ui/issues/issue-21291.rs b/src/test/ui/issues/issue-21291.rs new file mode 100644 index 00000000000..b351e22d862 --- /dev/null +++ b/src/test/ui/issues/issue-21291.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-21306.rs b/src/test/ui/issues/issue-21306.rs new file mode 100644 index 00000000000..b06a475e4df --- /dev/null +++ b/src/test/ui/issues/issue-21306.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-21361.rs b/src/test/ui/issues/issue-21361.rs new file mode 100644 index 00000000000..c970e77abb7 --- /dev/null +++ b/src/test/ui/issues/issue-21361.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-21384.rs b/src/test/ui/issues/issue-21384.rs new file mode 100644 index 00000000000..caa99a15982 --- /dev/null +++ b/src/test/ui/issues/issue-21384.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-21400.rs b/src/test/ui/issues/issue-21400.rs new file mode 100644 index 00000000000..4a85158d97a --- /dev/null +++ b/src/test/ui/issues/issue-21400.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/issues/issue-21475.rs b/src/test/ui/issues/issue-21475.rs new file mode 100644 index 00000000000..16d003aba7c --- /dev/null +++ b/src/test/ui/issues/issue-21475.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports)] +// 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/src/test/ui/issues/issue-21486.rs b/src/test/ui/issues/issue-21486.rs new file mode 100644 index 00000000000..46d6ccd56bd --- /dev/null +++ b/src/test/ui/issues/issue-21486.rs @@ -0,0 +1,77 @@ +// 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/src/test/ui/issues/issue-21655.rs b/src/test/ui/issues/issue-21655.rs new file mode 100644 index 00000000000..d1cd4ec7b8a --- /dev/null +++ b/src/test/ui/issues/issue-21655.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-2170-exe.rs b/src/test/ui/issues/issue-2170-exe.rs new file mode 100644 index 00000000000..a89579706c8 --- /dev/null +++ b/src/test/ui/issues/issue-2170-exe.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-21721.rs b/src/test/ui/issues/issue-21721.rs new file mode 100644 index 00000000000..4c1411e1ecf --- /dev/null +++ b/src/test/ui/issues/issue-21721.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-2190-1.rs b/src/test/ui/issues/issue-2190-1.rs new file mode 100644 index 00000000000..e67a924b9ee --- /dev/null +++ b/src/test/ui/issues/issue-2190-1.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-21909.rs b/src/test/ui/issues/issue-21909.rs new file mode 100644 index 00000000000..7cb558d9a4f --- /dev/null +++ b/src/test/ui/issues/issue-21909.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-21922.rs b/src/test/ui/issues/issue-21922.rs new file mode 100644 index 00000000000..9727b2efe9a --- /dev/null +++ b/src/test/ui/issues/issue-21922.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-22008.rs b/src/test/ui/issues/issue-22008.rs new file mode 100644 index 00000000000..00425582266 --- /dev/null +++ b/src/test/ui/issues/issue-22008.rs @@ -0,0 +1,9 @@ +// run-pass +pub fn main() { + let command = "a"; + + match command { + "foo" => println!("foo"), + _ => println!("{}", command), + } +} diff --git a/src/test/ui/issues/issue-22036.rs b/src/test/ui/issues/issue-22036.rs new file mode 100644 index 00000000000..30da2130a31 --- /dev/null +++ b/src/test/ui/issues/issue-22036.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-2214.rs b/src/test/ui/issues/issue-2214.rs new file mode 100644 index 00000000000..22f33545cb9 --- /dev/null +++ b/src/test/ui/issues/issue-2214.rs @@ -0,0 +1,41 @@ +// 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}; + + #[link_name = "m"] + extern { + #[cfg(any(unix, 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; + } +} + +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/src/test/ui/issues/issue-2216.rs b/src/test/ui/issues/issue-2216.rs new file mode 100644 index 00000000000..fa712edcd1b --- /dev/null +++ b/src/test/ui/issues/issue-2216.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unreachable_code)] +pub fn main() { + let mut x = 0; + + 'foo: loop { + 'bar: loop { + 'quux: loop { + if 1 == 2 { + break 'foo; + } + else { + break 'bar; + } + } + continue 'foo; + } + x = 42; + break; + } + + println!("{}", x); + assert_eq!(x, 42); +} diff --git a/src/test/ui/issues/issue-22258.rs b/src/test/ui/issues/issue-22258.rs new file mode 100644 index 00000000000..93ead5818d5 --- /dev/null +++ b/src/test/ui/issues/issue-22258.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-22346.rs b/src/test/ui/issues/issue-22346.rs new file mode 100644 index 00000000000..5f6d9dcc9ae --- /dev/null +++ b/src/test/ui/issues/issue-22346.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-22403.rs b/src/test/ui/issues/issue-22403.rs new file mode 100644 index 00000000000..8d855909435 --- /dev/null +++ b/src/test/ui/issues/issue-22403.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + let x = Box::new([1, 2, 3]); + let y = x as Box<[i32]>; + println!("y: {:?}", y); +} diff --git a/src/test/ui/issues/issue-22426.rs b/src/test/ui/issues/issue-22426.rs new file mode 100644 index 00000000000..adf060a8292 --- /dev/null +++ b/src/test/ui/issues/issue-22426.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + match 42 { + x if x < 7 => (), + _ => () + } +} diff --git a/src/test/ui/issues/issue-22463.rs b/src/test/ui/issues/issue-22463.rs new file mode 100644 index 00000000000..fdf5a2fca72 --- /dev/null +++ b/src/test/ui/issues/issue-22463.rs @@ -0,0 +1,20 @@ +// run-pass +macro_rules! items { + () => { + type A = (); + fn a() {} + } +} + +trait Foo { + type A; + fn a(); +} + +impl Foo for () { + items!(); +} + +fn main() { + +} diff --git a/src/test/ui/issues/issue-22536-copy-mustnt-zero.rs b/src/test/ui/issues/issue-22536-copy-mustnt-zero.rs new file mode 100644 index 00000000000..017f36484c1 --- /dev/null +++ b/src/test/ui/issues/issue-22536-copy-mustnt-zero.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-22546.rs b/src/test/ui/issues/issue-22546.rs new file mode 100644 index 00000000000..c26e457f9e4 --- /dev/null +++ b/src/test/ui/issues/issue-22546.rs @@ -0,0 +1,52 @@ +// 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/src/test/ui/issues/issue-22577.rs b/src/test/ui/issues/issue-22577.rs new file mode 100644 index 00000000000..24f4f60aa2f --- /dev/null +++ b/src/test/ui/issues/issue-22577.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-22629.rs b/src/test/ui/issues/issue-22629.rs new file mode 100644 index 00000000000..7beeb126ee4 --- /dev/null +++ b/src/test/ui/issues/issue-22629.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-22828.rs b/src/test/ui/issues/issue-22828.rs new file mode 100644 index 00000000000..adf4dd6ce75 --- /dev/null +++ b/src/test/ui/issues/issue-22828.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +// Test transitive analysis for associated types. Collected types +// should be normalized and new obligations generated. + +// pretty-expanded FIXME #23616 + +trait Foo { + type A; + fn foo(&self) {} +} + +impl Foo for usize { + type A = usize; +} + +struct Bar { inner: T::A } + +fn is_send() {} + +fn main() { + is_send::>(); +} diff --git a/src/test/ui/issues/issue-2284.rs b/src/test/ui/issues/issue-2284.rs new file mode 100644 index 00000000000..6f2c958341b --- /dev/null +++ b/src/test/ui/issues/issue-2284.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-22864-1.rs b/src/test/ui/issues/issue-22864-1.rs new file mode 100644 index 00000000000..0fad5433d6c --- /dev/null +++ b/src/test/ui/issues/issue-22864-1.rs @@ -0,0 +1,7 @@ +// run-pass +pub fn main() { + struct Fun(F); + let f = Fun(|x| 3*x); + let Fun(g) = f; + println!("{:?}",g(4)); +} diff --git a/src/test/ui/issues/issue-22864-2.rs b/src/test/ui/issues/issue-22864-2.rs new file mode 100644 index 00000000000..4aa9e3e086b --- /dev/null +++ b/src/test/ui/issues/issue-22864-2.rs @@ -0,0 +1,7 @@ +// run-pass +// ignore-emscripten no threads support + +pub fn main() { + let f = || || 0; + std::thread::spawn(f()); +} diff --git a/src/test/ui/issues/issue-2288.rs b/src/test/ui/issues/issue-2288.rs new file mode 100644 index 00000000000..c74e53fca60 --- /dev/null +++ b/src/test/ui/issues/issue-2288.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/issues/issue-22992-2.rs b/src/test/ui/issues/issue-22992-2.rs new file mode 100644 index 00000000000..042af40eda6 --- /dev/null +++ b/src/test/ui/issues/issue-22992-2.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-22992.rs b/src/test/ui/issues/issue-22992.rs new file mode 100644 index 00000000000..e2ae1f96ee5 --- /dev/null +++ b/src/test/ui/issues/issue-22992.rs @@ -0,0 +1,76 @@ +// 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/src/test/ui/issues/issue-23036.rs b/src/test/ui/issues/issue-23036.rs new file mode 100644 index 00000000000..a307e7eed95 --- /dev/null +++ b/src/test/ui/issues/issue-23036.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-2316-c.rs b/src/test/ui/issues/issue-2316-c.rs new file mode 100644 index 00000000000..d975aa695c8 --- /dev/null +++ b/src/test/ui/issues/issue-2316-c.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-23208.rs b/src/test/ui/issues/issue-23208.rs new file mode 100644 index 00000000000..fd4ffe5d6e1 --- /dev/null +++ b/src/test/ui/issues/issue-23208.rs @@ -0,0 +1,26 @@ +// run-pass +trait TheTrait : TheSuperTrait<::Item> { + type Item; +} + +trait TheSuperTrait { + fn get(&self) -> T; +} + +impl TheTrait for i32 { + type Item = u32; +} + +impl TheSuperTrait for i32 { + fn get(&self) -> u32 { + *self as u32 + } +} + +fn foo>(t: &T) -> u32 { + t.get() +} + +fn main() { + foo::(&22); +} diff --git a/src/test/ui/issues/issue-23261.rs b/src/test/ui/issues/issue-23261.rs new file mode 100644 index 00000000000..e21f86351ee --- /dev/null +++ b/src/test/ui/issues/issue-23261.rs @@ -0,0 +1,61 @@ +// 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/src/test/ui/issues/issue-23304-1.rs b/src/test/ui/issues/issue-23304-1.rs new file mode 100644 index 00000000000..1805c1c19b9 --- /dev/null +++ b/src/test/ui/issues/issue-23304-1.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-23304-2.rs b/src/test/ui/issues/issue-23304-2.rs new file mode 100644 index 00000000000..6376fdb6545 --- /dev/null +++ b/src/test/ui/issues/issue-23304-2.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-23311.rs b/src/test/ui/issues/issue-23311.rs new file mode 100644 index 00000000000..f275c6338b1 --- /dev/null +++ b/src/test/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. + +#![feature(slice_patterns)] + +fn main() { + match "foo".as_bytes() { + b"food" => (), + &[b'f', ..] => (), + _ => () + } +} diff --git a/src/test/ui/issues/issue-23336.rs b/src/test/ui/issues/issue-23336.rs new file mode 100644 index 00000000000..cd71d7eed89 --- /dev/null +++ b/src/test/ui/issues/issue-23336.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs b/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs new file mode 100644 index 00000000000..823be8c832d --- /dev/null +++ b/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs @@ -0,0 +1,164 @@ +// 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/src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs b/src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs new file mode 100644 index 00000000000..d45aaa843fb --- /dev/null +++ b/src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-23433.rs b/src/test/ui/issues/issue-23433.rs new file mode 100644 index 00000000000..d4fbbde62ff --- /dev/null +++ b/src/test/ui/issues/issue-23433.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-23485.rs b/src/test/ui/issues/issue-23485.rs new file mode 100644 index 00000000000..1dd3d9293bc --- /dev/null +++ b/src/test/ui/issues/issue-23485.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/issues/issue-23491.rs b/src/test/ui/issues/issue-23491.rs new file mode 100644 index 00000000000..d2ded88aeff --- /dev/null +++ b/src/test/ui/issues/issue-23491.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +#![feature(box_syntax)] + +struct Node(T); + +fn main() { + let x: Box> = box Node([]); +} diff --git a/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs new file mode 100644 index 00000000000..6ef7fd42ec6 --- /dev/null +++ b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs @@ -0,0 +1,258 @@ +// 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) + } + }; + + 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/src/test/ui/issues/issue-23649-1.rs b/src/test/ui/issues/issue-23649-1.rs new file mode 100644 index 00000000000..fc0c9a605fa --- /dev/null +++ b/src/test/ui/issues/issue-23649-1.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-23649-2.rs b/src/test/ui/issues/issue-23649-2.rs new file mode 100644 index 00000000000..f5fb8b65020 --- /dev/null +++ b/src/test/ui/issues/issue-23649-2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-23699.rs b/src/test/ui/issues/issue-23699.rs new file mode 100644 index 00000000000..952548837e4 --- /dev/null +++ b/src/test/ui/issues/issue-23699.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-23781.rs b/src/test/ui/issues/issue-23781.rs new file mode 100644 index 00000000000..220ebdb1872 --- /dev/null +++ b/src/test/ui/issues/issue-23781.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-2380-b.rs b/src/test/ui/issues/issue-2380-b.rs new file mode 100644 index 00000000000..d708c7b4213 --- /dev/null +++ b/src/test/ui/issues/issue-2380-b.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-2380.rs + +// pretty-expanded FIXME #23616 + +extern crate a; + +pub fn main() { + a::f::<()>(); +} diff --git a/src/test/ui/issues/issue-23808.rs b/src/test/ui/issues/issue-23808.rs new file mode 100644 index 00000000000..0988b09fce9 --- /dev/null +++ b/src/test/ui/issues/issue-23808.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/issues/issue-23825.rs b/src/test/ui/issues/issue-23825.rs new file mode 100644 index 00000000000..a9f0095d2e2 --- /dev/null +++ b/src/test/ui/issues/issue-23825.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-2383.rs b/src/test/ui/issues/issue-2383.rs new file mode 100644 index 00000000000..06e61ce680b --- /dev/null +++ b/src/test/ui/issues/issue-2383.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-23833.rs b/src/test/ui/issues/issue-23833.rs new file mode 100644 index 00000000000..77dc5c50d7a --- /dev/null +++ b/src/test/ui/issues/issue-23833.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-23891.rs b/src/test/ui/issues/issue-23891.rs new file mode 100644 index 00000000000..73467f715cb --- /dev/null +++ b/src/test/ui/issues/issue-23891.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-23898.rs b/src/test/ui/issues/issue-23898.rs new file mode 100644 index 00000000000..a8787f279b7 --- /dev/null +++ b/src/test/ui/issues/issue-23898.rs @@ -0,0 +1,10 @@ +// run-pass +#![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/src/test/ui/issues/issue-23958.rs b/src/test/ui/issues/issue-23958.rs new file mode 100644 index 00000000000..7e90d758600 --- /dev/null +++ b/src/test/ui/issues/issue-23958.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-23968-const-not-overflow.rs b/src/test/ui/issues/issue-23968-const-not-overflow.rs new file mode 100644 index 00000000000..b9593021235 --- /dev/null +++ b/src/test/ui/issues/issue-23968-const-not-overflow.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-23992.rs b/src/test/ui/issues/issue-23992.rs new file mode 100644 index 00000000000..1ff44bd7f2d --- /dev/null +++ b/src/test/ui/issues/issue-23992.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-24010.rs b/src/test/ui/issues/issue-24010.rs new file mode 100644 index 00000000000..f1818533487 --- /dev/null +++ b/src/test/ui/issues/issue-24010.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-24086.rs b/src/test/ui/issues/issue-24086.rs new file mode 100644 index 00000000000..54622afbcfc --- /dev/null +++ b/src/test/ui/issues/issue-24086.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-2414-c.rs b/src/test/ui/issues/issue-2414-c.rs new file mode 100644 index 00000000000..f6fe9798067 --- /dev/null +++ b/src/test/ui/issues/issue-2414-c.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-2428.rs b/src/test/ui/issues/issue-2428.rs new file mode 100644 index 00000000000..94b830de3e6 --- /dev/null +++ b/src/test/ui/issues/issue-2428.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-24308.rs b/src/test/ui/issues/issue-24308.rs new file mode 100644 index 00000000000..9c39a5d2238 --- /dev/null +++ b/src/test/ui/issues/issue-24308.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-24313.rs b/src/test/ui/issues/issue-24313.rs new file mode 100644 index 00000000000..2c420dc056f --- /dev/null +++ b/src/test/ui/issues/issue-24313.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-24353.rs b/src/test/ui/issues/issue-24353.rs new file mode 100644 index 00000000000..f78255b7e2b --- /dev/null +++ b/src/test/ui/issues/issue-24353.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unreachable_code)] +fn main() { + return (); + + let x = (); + x +} diff --git a/src/test/ui/issues/issue-2445-b.rs b/src/test/ui/issues/issue-2445-b.rs new file mode 100644 index 00000000000..f369eae3af3 --- /dev/null +++ b/src/test/ui/issues/issue-2445-b.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-2445.rs b/src/test/ui/issues/issue-2445.rs new file mode 100644 index 00000000000..5730ce16574 --- /dev/null +++ b/src/test/ui/issues/issue-2445.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-24533.rs b/src/test/ui/issues/issue-24533.rs new file mode 100644 index 00000000000..8592bf43072 --- /dev/null +++ b/src/test/ui/issues/issue-24533.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs new file mode 100644 index 00000000000..48362d0bb62 --- /dev/null +++ b/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -0,0 +1,57 @@ +// 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 + +#![feature(bind_by_move_pattern_guards)] + +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/src/test/ui/issues/issue-24589.rs b/src/test/ui/issues/issue-24589.rs new file mode 100644 index 00000000000..6b03e14f961 --- /dev/null +++ b/src/test/ui/issues/issue-24589.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-2463.rs b/src/test/ui/issues/issue-2463.rs new file mode 100644 index 00000000000..d24a47c53d9 --- /dev/null +++ b/src/test/ui/issues/issue-2463.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs new file mode 100644 index 00000000000..5b1b1389ceb --- /dev/null +++ b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs @@ -0,0 +1,10 @@ +#![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/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs new file mode 100644 index 00000000000..215145a64b1 --- /dev/null +++ b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs @@ -0,0 +1,27 @@ +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/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs new file mode 100644 index 00000000000..773792c7a3f --- /dev/null +++ b/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:issue-24687-lib.rs +// compile-flags:-g + +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/src/test/ui/issues/issue-2472.rs b/src/test/ui/issues/issue-2472.rs new file mode 100644 index 00000000000..c790bc2d095 --- /dev/null +++ b/src/test/ui/issues/issue-2472.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-24779.rs b/src/test/ui/issues/issue-24779.rs new file mode 100644 index 00000000000..f1283d0dcf5 --- /dev/null +++ b/src/test/ui/issues/issue-24779.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + assert_eq!((||||42)()(), 42); +} diff --git a/src/test/ui/issues/issue-24805-dropck-itemless.rs b/src/test/ui/issues/issue-24805-dropck-itemless.rs new file mode 100644 index 00000000000..555eefeb3a1 --- /dev/null +++ b/src/test/ui/issues/issue-24805-dropck-itemless.rs @@ -0,0 +1,77 @@ +// 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/src/test/ui/issues/issue-24945-repeat-dash-opts.rs b/src/test/ui/issues/issue-24945-repeat-dash-opts.rs new file mode 100644 index 00000000000..cf3834952c6 --- /dev/null +++ b/src/test/ui/issues/issue-24945-repeat-dash-opts.rs @@ -0,0 +1,9 @@ +// 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 + +fn main() { + assert_eq!(1, 1); +} diff --git a/src/test/ui/issues/issue-24947.rs b/src/test/ui/issues/issue-24947.rs new file mode 100644 index 00000000000..23705b4c9e7 --- /dev/null +++ b/src/test/ui/issues/issue-24947.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-24954.rs b/src/test/ui/issues/issue-24954.rs new file mode 100644 index 00000000000..0177dd4eae5 --- /dev/null +++ b/src/test/ui/issues/issue-24954.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-25089.rs b/src/test/ui/issues/issue-25089.rs new file mode 100644 index 00000000000..cf261d43c55 --- /dev/null +++ b/src/test/ui/issues/issue-25089.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-25145.rs b/src/test/ui/issues/issue-25145.rs new file mode 100644 index 00000000000..f5ae28fbbab --- /dev/null +++ b/src/test/ui/issues/issue-25145.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-25185.rs b/src/test/ui/issues/issue-25185.rs new file mode 100644 index 00000000000..383c9a1e9c4 --- /dev/null +++ b/src/test/ui/issues/issue-25185.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-2526-a.rs b/src/test/ui/issues/issue-2526-a.rs new file mode 100644 index 00000000000..f3fdc0bd377 --- /dev/null +++ b/src/test/ui/issues/issue-2526-a.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-25279.rs b/src/test/ui/issues/issue-25279.rs new file mode 100644 index 00000000000..fdc516d3761 --- /dev/null +++ b/src/test/ui/issues/issue-25279.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-25339.rs b/src/test/ui/issues/issue-25339.rs new file mode 100644 index 00000000000..6f8ec700951 --- /dev/null +++ b/src/test/ui/issues/issue-25339.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![feature(associated_type_defaults)] + +use std::marker::PhantomData; + +pub trait Routing { + type Output; + fn resolve(&self, input: I); +} + +pub trait ToRouting { + type Input; + type Routing : ?Sized = dyn Routing; + fn to_routing(self) -> Self::Routing; +} + +pub struct Mount> { + action: R, + _marker: PhantomData +} + +impl> Mount { + pub fn create>(mount: &str, input: T) { + input.to_routing(); + } +} + +fn main() { +} diff --git a/src/test/ui/issues/issue-25343.rs b/src/test/ui/issues/issue-25343.rs new file mode 100644 index 00000000000..95a0bd9155d --- /dev/null +++ b/src/test/ui/issues/issue-25343.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-25467.rs b/src/test/ui/issues/issue-25467.rs new file mode 100644 index 00000000000..31ac5f0f34b --- /dev/null +++ b/src/test/ui/issues/issue-25467.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-25497.rs b/src/test/ui/issues/issue-25497.rs new file mode 100644 index 00000000000..25f5ab90f7f --- /dev/null +++ b/src/test/ui/issues/issue-25497.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-2550.rs b/src/test/ui/issues/issue-2550.rs new file mode 100644 index 00000000000..04ec66b80d7 --- /dev/null +++ b/src/test/ui/issues/issue-2550.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-25515.rs b/src/test/ui/issues/issue-25515.rs new file mode 100644 index 00000000000..e7b9ea3acfc --- /dev/null +++ b/src/test/ui/issues/issue-25515.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-25549-multiple-drop.rs b/src/test/ui/issues/issue-25549-multiple-drop.rs new file mode 100644 index 00000000000..25a2da707dc --- /dev/null +++ b/src/test/ui/issues/issue-25549-multiple-drop.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-25679.rs b/src/test/ui/issues/issue-25679.rs new file mode 100644 index 00000000000..89544c9eb88 --- /dev/null +++ b/src/test/ui/issues/issue-25679.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-25693.rs b/src/test/ui/issues/issue-25693.rs new file mode 100644 index 00000000000..9af0ba100e8 --- /dev/null +++ b/src/test/ui/issues/issue-25693.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-25700-1.rs b/src/test/ui/issues/issue-25700-1.rs new file mode 100644 index 00000000000..7bc9673a5be --- /dev/null +++ b/src/test/ui/issues/issue-25700-1.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-25700-2.rs b/src/test/ui/issues/issue-25700-2.rs new file mode 100644 index 00000000000..b161e68abaf --- /dev/null +++ b/src/test/ui/issues/issue-25700-2.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-25746-bool-transmute.rs b/src/test/ui/issues/issue-25746-bool-transmute.rs new file mode 100644 index 00000000000..bc2f4a7c1b7 --- /dev/null +++ b/src/test/ui/issues/issue-25746-bool-transmute.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-25757.rs b/src/test/ui/issues/issue-25757.rs new file mode 100644 index 00000000000..ec1864d7deb --- /dev/null +++ b/src/test/ui/issues/issue-25757.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-25810.rs b/src/test/ui/issues/issue-25810.rs new file mode 100644 index 00000000000..f32216f3254 --- /dev/null +++ b/src/test/ui/issues/issue-25810.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-25916.rs b/src/test/ui/issues/issue-25916.rs new file mode 100644 index 00000000000..0b415947965 --- /dev/null +++ b/src/test/ui/issues/issue-25916.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-26127.rs b/src/test/ui/issues/issue-26127.rs new file mode 100644 index 00000000000..cb479a23085 --- /dev/null +++ b/src/test/ui/issues/issue-26127.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-26251.rs b/src/test/ui/issues/issue-26251.rs new file mode 100644 index 00000000000..0434ef9e5a9 --- /dev/null +++ b/src/test/ui/issues/issue-26251.rs @@ -0,0 +1,13 @@ +// run-pass +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/src/test/ui/issues/issue-2631-b.rs b/src/test/ui/issues/issue-2631-b.rs new file mode 100644 index 00000000000..c7f6728e3f2 --- /dev/null +++ b/src/test/ui/issues/issue-2631-b.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-26322.rs b/src/test/ui/issues/issue-26322.rs new file mode 100644 index 00000000000..c1dc80eb7c5 --- /dev/null +++ b/src/test/ui/issues/issue-26322.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-2633-2.rs b/src/test/ui/issues/issue-2633-2.rs new file mode 100644 index 00000000000..02c1a166301 --- /dev/null +++ b/src/test/ui/issues/issue-2633-2.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-2633.rs b/src/test/ui/issues/issue-2633.rs new file mode 100644 index 00000000000..7e8cea75fc8 --- /dev/null +++ b/src/test/ui/issues/issue-2633.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-2642.rs b/src/test/ui/issues/issue-2642.rs new file mode 100644 index 00000000000..95c5632258e --- /dev/null +++ b/src/test/ui/issues/issue-2642.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn f() { + let _x: usize = loop { loop { break; } }; +} + +pub fn main() { +} diff --git a/src/test/ui/issues/issue-26468.rs b/src/test/ui/issues/issue-26468.rs new file mode 100644 index 00000000000..71cc90e8bd1 --- /dev/null +++ b/src/test/ui/issues/issue-26468.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-26484.rs b/src/test/ui/issues/issue-26484.rs new file mode 100644 index 00000000000..3b40b3dd8f0 --- /dev/null +++ b/src/test/ui/issues/issue-26484.rs @@ -0,0 +1,11 @@ +// run-pass +// compile-flags:-g + +fn helper bool>(_f: F) { + print!(""); +} + +fn main() { + let cond = 0; + helper(|v| v == cond) +} diff --git a/src/test/ui/issues/issue-26641.rs b/src/test/ui/issues/issue-26641.rs new file mode 100644 index 00000000000..4b6f2c2b3bc --- /dev/null +++ b/src/test/ui/issues/issue-26641.rs @@ -0,0 +1,6 @@ +// run-pass +struct Parser<'a>(Box); + +fn main() { + let _x = Parser(Box::new(|_|{})); +} diff --git a/src/test/ui/issues/issue-26655.rs b/src/test/ui/issues/issue-26655.rs new file mode 100644 index 00000000000..4c01183a440 --- /dev/null +++ b/src/test/ui/issues/issue-26655.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-26709.rs b/src/test/ui/issues/issue-26709.rs new file mode 100644 index 00000000000..281ae13399d --- /dev/null +++ b/src/test/ui/issues/issue-26709.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-26802.rs b/src/test/ui/issues/issue-26802.rs new file mode 100644 index 00000000000..307a6716098 --- /dev/null +++ b/src/test/ui/issues/issue-26802.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-26805.rs b/src/test/ui/issues/issue-26805.rs new file mode 100644 index 00000000000..bcf8a673191 --- /dev/null +++ b/src/test/ui/issues/issue-26805.rs @@ -0,0 +1,6 @@ +// run-pass +struct NonOrd; + +fn main() { + let _: Box> = Box::new(vec![NonOrd].into_iter()); +} diff --git a/src/test/ui/issues/issue-26873-multifile.rs b/src/test/ui/issues/issue-26873-multifile.rs new file mode 100644 index 00000000000..da2acf6c9f7 --- /dev/null +++ b/src/test/ui/issues/issue-26873-multifile.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-26873-multifile/A/B.rs b/src/test/ui/issues/issue-26873-multifile/A/B.rs new file mode 100644 index 00000000000..ab7b0d81605 --- /dev/null +++ b/src/test/ui/issues/issue-26873-multifile/A/B.rs @@ -0,0 +1,4 @@ +// run-pass +use super::*; + +pub struct S; diff --git a/src/test/ui/issues/issue-26873-multifile/A/C.rs b/src/test/ui/issues/issue-26873-multifile/A/C.rs new file mode 100644 index 00000000000..b287283df53 --- /dev/null +++ b/src/test/ui/issues/issue-26873-multifile/A/C.rs @@ -0,0 +1,6 @@ +// run-pass +use super::*; + +use super::B::S; + +pub struct T { i: i32 } diff --git a/src/test/ui/issues/issue-26873-multifile/A/mod.rs b/src/test/ui/issues/issue-26873-multifile/A/mod.rs new file mode 100644 index 00000000000..0f18772bf1b --- /dev/null +++ b/src/test/ui/issues/issue-26873-multifile/A/mod.rs @@ -0,0 +1,5 @@ +// run-pass +pub mod B; +pub mod C; + +pub use self::C::T; diff --git a/src/test/ui/issues/issue-26873-multifile/compiletest-ignore-dir b/src/test/ui/issues/issue-26873-multifile/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/issues/issue-26873-multifile/mod.rs b/src/test/ui/issues/issue-26873-multifile/mod.rs new file mode 100644 index 00000000000..a1ba53f9191 --- /dev/null +++ b/src/test/ui/issues/issue-26873-multifile/mod.rs @@ -0,0 +1,4 @@ +// run-pass +mod A; + +use self::A::*; diff --git a/src/test/ui/issues/issue-26873-onefile.rs b/src/test/ui/issues/issue-26873-onefile.rs new file mode 100644 index 00000000000..f06c6499eb0 --- /dev/null +++ b/src/test/ui/issues/issue-26873-onefile.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-26996.rs b/src/test/ui/issues/issue-26996.rs new file mode 100644 index 00000000000..04382be27d7 --- /dev/null +++ b/src/test/ui/issues/issue-26996.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-27021.rs b/src/test/ui/issues/issue-27021.rs new file mode 100644 index 00000000000..30551375450 --- /dev/null +++ b/src/test/ui/issues/issue-27021.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-27054-primitive-binary-ops.rs b/src/test/ui/issues/issue-27054-primitive-binary-ops.rs new file mode 100644 index 00000000000..c6f925de5d7 --- /dev/null +++ b/src/test/ui/issues/issue-27054-primitive-binary-ops.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + let x = &mut 1; + assert_eq!(*x + { *x=2; 1 }, 2); +} diff --git a/src/test/ui/issues/issue-2708.rs b/src/test/ui/issues/issue-2708.rs new file mode 100644 index 00000000000..abd5e9507f8 --- /dev/null +++ b/src/test/ui/issues/issue-2708.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-2718.rs b/src/test/ui/issues/issue-2718.rs new file mode 100644 index 00000000000..6449337eea4 --- /dev/null +++ b/src/test/ui/issues/issue-2718.rs @@ -0,0 +1,327 @@ +// 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/src/test/ui/issues/issue-2723-b.rs b/src/test/ui/issues/issue-2723-b.rs new file mode 100644 index 00000000000..1910561d0ba --- /dev/null +++ b/src/test/ui/issues/issue-2723-b.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-27240.rs b/src/test/ui/issues/issue-27240.rs new file mode 100644 index 00000000000..a22db76b9bc --- /dev/null +++ b/src/test/ui/issues/issue-27240.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-27268.rs b/src/test/ui/issues/issue-27268.rs new file mode 100644 index 00000000000..161e2d4d204 --- /dev/null +++ b/src/test/ui/issues/issue-27268.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + const _C: &'static dyn Fn() = &||{}; +} diff --git a/src/test/ui/issues/issue-27320.rs b/src/test/ui/issues/issue-27320.rs new file mode 100644 index 00000000000..d1aa56b915b --- /dev/null +++ b/src/test/ui/issues/issue-27320.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-2734.rs b/src/test/ui/issues/issue-2734.rs new file mode 100644 index 00000000000..d449f6449aa --- /dev/null +++ b/src/test/ui/issues/issue-2734.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-2735-2.rs b/src/test/ui/issues/issue-2735-2.rs new file mode 100644 index 00000000000..70ebce9d35a --- /dev/null +++ b/src/test/ui/issues/issue-2735-2.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-2735-3.rs b/src/test/ui/issues/issue-2735-3.rs new file mode 100644 index 00000000000..23301537835 --- /dev/null +++ b/src/test/ui/issues/issue-2735-3.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-2735.rs b/src/test/ui/issues/issue-2735.rs new file mode 100644 index 00000000000..794c7d4edaa --- /dev/null +++ b/src/test/ui/issues/issue-2735.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-27401-dropflag-reinit.rs b/src/test/ui/issues/issue-27401-dropflag-reinit.rs new file mode 100644 index 00000000000..e137575c2f8 --- /dev/null +++ b/src/test/ui/issues/issue-27401-dropflag-reinit.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-2748-b.rs b/src/test/ui/issues/issue-2748-b.rs new file mode 100644 index 00000000000..8df735ac88e --- /dev/null +++ b/src/test/ui/issues/issue-2748-b.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-27639.rs b/src/test/ui/issues/issue-27639.rs new file mode 100644 index 00000000000..945fbad91f6 --- /dev/null +++ b/src/test/ui/issues/issue-27639.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-27859.rs b/src/test/ui/issues/issue-27859.rs new file mode 100644 index 00000000000..259d706fa2a --- /dev/null +++ b/src/test/ui/issues/issue-27859.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-27890.rs b/src/test/ui/issues/issue-27890.rs new file mode 100644 index 00000000000..9f85473380f --- /dev/null +++ b/src/test/ui/issues/issue-27890.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-27901.rs b/src/test/ui/issues/issue-27901.rs new file mode 100644 index 00000000000..ffd90b68983 --- /dev/null +++ b/src/test/ui/issues/issue-27901.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-27949.rs b/src/test/ui/issues/issue-27949.rs new file mode 100644 index 00000000000..e905da72aad --- /dev/null +++ b/src/test/ui/issues/issue-27949.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/issues/issue-27997.rs b/src/test/ui/issues/issue-27997.rs new file mode 100644 index 00000000000..dd74cf75249 --- /dev/null +++ b/src/test/ui/issues/issue-27997.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/issues/issue-28181.rs b/src/test/ui/issues/issue-28181.rs new file mode 100644 index 00000000000..c46e131c6ac --- /dev/null +++ b/src/test/ui/issues/issue-28181.rs @@ -0,0 +1,6 @@ +// run-pass +fn bar(f: F) -> usize where F: Fn([usize; 1]) -> usize { f([2]) } + +fn main() { + bar(|u| { u[0] }); +} diff --git a/src/test/ui/issues/issue-28498-must-work-ex1.rs b/src/test/ui/issues/issue-28498-must-work-ex1.rs new file mode 100644 index 00000000000..4699d3352ad --- /dev/null +++ b/src/test/ui/issues/issue-28498-must-work-ex1.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-28498-must-work-ex2.rs b/src/test/ui/issues/issue-28498-must-work-ex2.rs new file mode 100644 index 00000000000..cadf62461fd --- /dev/null +++ b/src/test/ui/issues/issue-28498-must-work-ex2.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-28498-ugeh-ex1.rs b/src/test/ui/issues/issue-28498-ugeh-ex1.rs new file mode 100644 index 00000000000..90cf2cddcf0 --- /dev/null +++ b/src/test/ui/issues/issue-28498-ugeh-ex1.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs new file mode 100644 index 00000000000..aea9fde5309 --- /dev/null +++ b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs new file mode 100644 index 00000000000..91ef5a7c98d --- /dev/null +++ b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs new file mode 100644 index 00000000000..808f3b6e81e --- /dev/null +++ b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/issues/issue-28550.rs b/src/test/ui/issues/issue-28550.rs new file mode 100644 index 00000000000..95583f80515 --- /dev/null +++ b/src/test/ui/issues/issue-28550.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-28676.rs b/src/test/ui/issues/issue-28676.rs new file mode 100644 index 00000000000..2b83478ca61 --- /dev/null +++ b/src/test/ui/issues/issue-28676.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/issues/issue-28777.rs b/src/test/ui/issues/issue-28777.rs new file mode 100644 index 00000000000..74de00adadb --- /dev/null +++ b/src/test/ui/issues/issue-28777.rs @@ -0,0 +1,21 @@ +// run-pass +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/src/test/ui/issues/issue-28828.rs b/src/test/ui/issues/issue-28828.rs new file mode 100644 index 00000000000..03968809eb7 --- /dev/null +++ b/src/test/ui/issues/issue-28828.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-28839.rs b/src/test/ui/issues/issue-28839.rs new file mode 100644 index 00000000000..73be87a0c1e --- /dev/null +++ b/src/test/ui/issues/issue-28839.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-2895.rs b/src/test/ui/issues/issue-2895.rs new file mode 100644 index 00000000000..d8c08996bc3 --- /dev/null +++ b/src/test/ui/issues/issue-2895.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-28950.rs b/src/test/ui/issues/issue-28950.rs new file mode 100644 index 00000000000..8b55f42f3f4 --- /dev/null +++ b/src/test/ui/issues/issue-28950.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-28983.rs b/src/test/ui/issues/issue-28983.rs new file mode 100644 index 00000000000..3db26a1ee5f --- /dev/null +++ b/src/test/ui/issues/issue-28983.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-29053.rs b/src/test/ui/issues/issue-29053.rs new file mode 100644 index 00000000000..34c4a0f8f3e --- /dev/null +++ b/src/test/ui/issues/issue-29053.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-29071-2.rs b/src/test/ui/issues/issue-29071-2.rs new file mode 100644 index 00000000000..f27bf0261db --- /dev/null +++ b/src/test/ui/issues/issue-29071-2.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-29092.rs b/src/test/ui/issues/issue-29092.rs new file mode 100644 index 00000000000..f20d2a424b0 --- /dev/null +++ b/src/test/ui/issues/issue-29092.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-29166.rs b/src/test/ui/issues/issue-29166.rs new file mode 100644 index 00000000000..ca819ba39a2 --- /dev/null +++ b/src/test/ui/issues/issue-29166.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-29227.rs b/src/test/ui/issues/issue-29227.rs new file mode 100644 index 00000000000..e9dfc2840e5 --- /dev/null +++ b/src/test/ui/issues/issue-29227.rs @@ -0,0 +1,142 @@ +// 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/src/test/ui/issues/issue-2935.rs b/src/test/ui/issues/issue-2935.rs new file mode 100644 index 00000000000..11641ca7380 --- /dev/null +++ b/src/test/ui/issues/issue-2935.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-2936.rs b/src/test/ui/issues/issue-2936.rs new file mode 100644 index 00000000000..6b932d01d55 --- /dev/null +++ b/src/test/ui/issues/issue-2936.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-29466.rs b/src/test/ui/issues/issue-29466.rs new file mode 100644 index 00000000000..f8785a63217 --- /dev/null +++ b/src/test/ui/issues/issue-29466.rs @@ -0,0 +1,3603 @@ +// 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/src/test/ui/issues/issue-29485.rs b/src/test/ui/issues/issue-29485.rs new file mode 100644 index 00000000000..6b2fb7126e3 --- /dev/null +++ b/src/test/ui/issues/issue-29485.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-29488.rs b/src/test/ui/issues/issue-29488.rs new file mode 100644 index 00000000000..3c9a6a80dbf --- /dev/null +++ b/src/test/ui/issues/issue-29488.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-29522.rs b/src/test/ui/issues/issue-29522.rs new file mode 100644 index 00000000000..3d2de5ef63a --- /dev/null +++ b/src/test/ui/issues/issue-29522.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-29663.rs b/src/test/ui/issues/issue-29663.rs new file mode 100644 index 00000000000..e2e89a8bfa3 --- /dev/null +++ b/src/test/ui/issues/issue-29663.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/issues/issue-29668.rs b/src/test/ui/issues/issue-29668.rs new file mode 100644 index 00000000000..3d6c27bcda1 --- /dev/null +++ b/src/test/ui/issues/issue-29668.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-29746.rs b/src/test/ui/issues/issue-29746.rs new file mode 100644 index 00000000000..428cc637f55 --- /dev/null +++ b/src/test/ui/issues/issue-29746.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-29844.rs b/src/test/ui/issues/issue-29844.rs new file mode 100644 index 00000000000..e08942da5e4 --- /dev/null +++ b/src/test/ui/issues/issue-29844.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-2989.rs b/src/test/ui/issues/issue-2989.rs new file mode 100644 index 00000000000..c0b67374370 --- /dev/null +++ b/src/test/ui/issues/issue-2989.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-29914-2.rs b/src/test/ui/issues/issue-29914-2.rs new file mode 100644 index 00000000000..626de269d95 --- /dev/null +++ b/src/test/ui/issues/issue-29914-2.rs @@ -0,0 +1,6 @@ +// run-pass +const ARR: [usize; 5] = [5, 4, 3, 2, 1]; + +fn main() { + assert_eq!(3, ARR[ARR[3]]); +} diff --git a/src/test/ui/issues/issue-29914-3.rs b/src/test/ui/issues/issue-29914-3.rs new file mode 100644 index 00000000000..1c6c64eb316 --- /dev/null +++ b/src/test/ui/issues/issue-29914-3.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-29914.rs b/src/test/ui/issues/issue-29914.rs new file mode 100644 index 00000000000..6da63664dfa --- /dev/null +++ b/src/test/ui/issues/issue-29914.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-29927-1.rs b/src/test/ui/issues/issue-29927-1.rs new file mode 100644 index 00000000000..a236e491375 --- /dev/null +++ b/src/test/ui/issues/issue-29927-1.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +const fn f() -> usize { + 5 +} +struct A { + field: usize, +} +fn main() { + let _ = [0; f()]; +} diff --git a/src/test/ui/issues/issue-29927.rs b/src/test/ui/issues/issue-29927.rs new file mode 100644 index 00000000000..3385e4e6e94 --- /dev/null +++ b/src/test/ui/issues/issue-29927.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +struct A { + field: usize, +} +const fn f() -> usize { + 5 +} +fn main() { + let _ = [0; f()]; +} diff --git a/src/test/ui/issues/issue-29948.rs b/src/test/ui/issues/issue-29948.rs new file mode 100644 index 00000000000..8ede8143ea6 --- /dev/null +++ b/src/test/ui/issues/issue-29948.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/issues/issue-30018-nopanic.rs b/src/test/ui/issues/issue-30018-nopanic.rs new file mode 100644 index 00000000000..291bab2736d --- /dev/null +++ b/src/test/ui/issues/issue-30018-nopanic.rs @@ -0,0 +1,103 @@ +// 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/src/test/ui/issues/issue-30018-panic.rs b/src/test/ui/issues/issue-30018-panic.rs new file mode 100644 index 00000000000..50749b0c742 --- /dev/null +++ b/src/test/ui/issues/issue-30018-panic.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-30081.rs b/src/test/ui/issues/issue-30081.rs new file mode 100644 index 00000000000..e7fca96ed9e --- /dev/null +++ b/src/test/ui/issues/issue-30081.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-3012-2.rs b/src/test/ui/issues/issue-3012-2.rs new file mode 100644 index 00000000000..7d32c51f569 --- /dev/null +++ b/src/test/ui/issues/issue-3012-2.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-3026.rs b/src/test/ui/issues/issue-3026.rs new file mode 100644 index 00000000000..1dea8134fba --- /dev/null +++ b/src/test/ui/issues/issue-3026.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-3037.rs b/src/test/ui/issues/issue-3037.rs new file mode 100644 index 00000000000..ff4d32c2840 --- /dev/null +++ b/src/test/ui/issues/issue-3037.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-30371.rs b/src/test/ui/issues/issue-30371.rs new file mode 100644 index 00000000000..58521b95cf6 --- /dev/null +++ b/src/test/ui/issues/issue-30371.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-30490.rs b/src/test/ui/issues/issue-30490.rs new file mode 100644 index 00000000000..76e72246887 --- /dev/null +++ b/src/test/ui/issues/issue-30490.rs @@ -0,0 +1,102 @@ +// 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/src/test/ui/issues/issue-3052.rs b/src/test/ui/issues/issue-3052.rs new file mode 100644 index 00000000000..ee2456da3e2 --- /dev/null +++ b/src/test/ui/issues/issue-3052.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-30530.rs b/src/test/ui/issues/issue-30530.rs new file mode 100644 index 00000000000..111fb8aa506 --- /dev/null +++ b/src/test/ui/issues/issue-30530.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-30615.rs b/src/test/ui/issues/issue-30615.rs new file mode 100644 index 00000000000..c718449d84e --- /dev/null +++ b/src/test/ui/issues/issue-30615.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + &0u8 as *const u8 as *const dyn PartialEq; + &[0u8] as *const [u8; 1] as *const [u8]; +} diff --git a/src/test/ui/issues/issue-30756.rs b/src/test/ui/issues/issue-30756.rs new file mode 100644 index 00000000000..836db951bb7 --- /dev/null +++ b/src/test/ui/issues/issue-30756.rs @@ -0,0 +1,7 @@ +// run-pass +#![forbid(unsafe_code)] + +thread_local!(static FOO: u8 = 1); + +fn main() { +} diff --git a/src/test/ui/issues/issue-30891.rs b/src/test/ui/issues/issue-30891.rs new file mode 100644 index 00000000000..30f55e0bd64 --- /dev/null +++ b/src/test/ui/issues/issue-30891.rs @@ -0,0 +1,10 @@ +// run-pass +const ERROR_CONST: bool = true; + +fn get() -> bool { + false || ERROR_CONST +} + +pub fn main() { + assert_eq!(get(), true); +} diff --git a/src/test/ui/issues/issue-3091.rs b/src/test/ui/issues/issue-3091.rs new file mode 100644 index 00000000000..0c0a412420a --- /dev/null +++ b/src/test/ui/issues/issue-3091.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x = 1; + let y = 1; + assert_eq!(&x, &y); +} diff --git a/src/test/ui/issues/issue-3109.rs b/src/test/ui/issues/issue-3109.rs new file mode 100644 index 00000000000..bd807cad753 --- /dev/null +++ b/src/test/ui/issues/issue-3109.rs @@ -0,0 +1,4 @@ +// run-pass +pub fn main() { + println!("{:?}", ("hi there!", "you")); +} diff --git a/src/test/ui/issues/issue-3121.rs b/src/test/ui/issues/issue-3121.rs new file mode 100644 index 00000000000..f7bbfa9f6f4 --- /dev/null +++ b/src/test/ui/issues/issue-3121.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-31267-additional.rs b/src/test/ui/issues/issue-31267-additional.rs new file mode 100644 index 00000000000..70dce2c9490 --- /dev/null +++ b/src/test/ui/issues/issue-31267-additional.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-31267.rs b/src/test/ui/issues/issue-31267.rs new file mode 100644 index 00000000000..50843c89eb4 --- /dev/null +++ b/src/test/ui/issues/issue-31267.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-31299.rs b/src/test/ui/issues/issue-31299.rs new file mode 100644 index 00000000000..abed18d81f8 --- /dev/null +++ b/src/test/ui/issues/issue-31299.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-3136-b.rs b/src/test/ui/issues/issue-3136-b.rs new file mode 100644 index 00000000000..c4ca7236e76 --- /dev/null +++ b/src/test/ui/issues/issue-3136-b.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-3136-a.rc + +// pretty-expanded FIXME #23616 + +extern crate issue_3136_a; + +pub fn main() {} diff --git a/src/test/ui/issues/issue-31702.rs b/src/test/ui/issues/issue-31702.rs new file mode 100644 index 00000000000..5b24eead345 --- /dev/null +++ b/src/test/ui/issues/issue-31702.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-31776.rs b/src/test/ui/issues/issue-31776.rs new file mode 100644 index 00000000000..c0d2c91e577 --- /dev/null +++ b/src/test/ui/issues/issue-31776.rs @@ -0,0 +1,57 @@ +// 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) {} + } + } +} + +// ------------------------------------------------------ + +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 + } +} + +// ------------------------------------------------------ + +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/src/test/ui/issues/issue-32008.rs b/src/test/ui/issues/issue-32008.rs new file mode 100644 index 00000000000..6c2e206796f --- /dev/null +++ b/src/test/ui/issues/issue-32008.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-3211.rs b/src/test/ui/issues/issue-3211.rs new file mode 100644 index 00000000000..49dd4fa7360 --- /dev/null +++ b/src/test/ui/issues/issue-3211.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-3220.rs b/src/test/ui/issues/issue-3220.rs new file mode 100644 index 00000000000..7dc672edb54 --- /dev/null +++ b/src/test/ui/issues/issue-3220.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-32292.rs b/src/test/ui/issues/issue-32292.rs new file mode 100644 index 00000000000..99b865391de --- /dev/null +++ b/src/test/ui/issues/issue-32292.rs @@ -0,0 +1,9 @@ +// run-pass +#![deny(warnings)] + +#[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] +struct Foo; + +fn main() { + let _ = Foo; +} diff --git a/src/test/ui/issues/issue-32389.rs b/src/test/ui/issues/issue-32389.rs new file mode 100644 index 00000000000..cc94cc819d6 --- /dev/null +++ b/src/test/ui/issues/issue-32389.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-32518.rs b/src/test/ui/issues/issue-32518.rs new file mode 100644 index 00000000000..808b40f71b3 --- /dev/null +++ b/src/test/ui/issues/issue-32518.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-32805.rs b/src/test/ui/issues/issue-32805.rs new file mode 100644 index 00000000000..23c19473903 --- /dev/null +++ b/src/test/ui/issues/issue-32805.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-3290.rs b/src/test/ui/issues/issue-3290.rs new file mode 100644 index 00000000000..63e1b28a60a --- /dev/null +++ b/src/test/ui/issues/issue-3290.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut x: Box<_> = box 3; + x = x; + assert_eq!(*x, 3); +} diff --git a/src/test/ui/issues/issue-32947.rs b/src/test/ui/issues/issue-32947.rs new file mode 100644 index 00000000000..b07def21e88 --- /dev/null +++ b/src/test/ui/issues/issue-32947.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-33096.rs b/src/test/ui/issues/issue-33096.rs new file mode 100644 index 00000000000..f0b472e2fe8 --- /dev/null +++ b/src/test/ui/issues/issue-33096.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags: -g + +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/src/test/ui/issues/issue-33185.rs b/src/test/ui/issues/issue-33185.rs new file mode 100644 index 00000000000..0d6669146a6 --- /dev/null +++ b/src/test/ui/issues/issue-33185.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-33187.rs b/src/test/ui/issues/issue-33187.rs new file mode 100644 index 00000000000..5226f9faf56 --- /dev/null +++ b/src/test/ui/issues/issue-33187.rs @@ -0,0 +1,18 @@ +// run-pass +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/src/test/ui/issues/issue-33202.rs b/src/test/ui/issues/issue-33202.rs new file mode 100644 index 00000000000..11b89ae1b47 --- /dev/null +++ b/src/test/ui/issues/issue-33202.rs @@ -0,0 +1,9 @@ +// run-pass +#[repr(C)] +pub enum CPOption { + PSome(T), +} + +fn main() { + println!("sizeof CPOption {}", std::mem::size_of::>()); +} diff --git a/src/test/ui/issues/issue-333.rs b/src/test/ui/issues/issue-333.rs new file mode 100644 index 00000000000..0753aaa0797 --- /dev/null +++ b/src/test/ui/issues/issue-333.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-33387.rs b/src/test/ui/issues/issue-33387.rs new file mode 100644 index 00000000000..499fa7c1f27 --- /dev/null +++ b/src/test/ui/issues/issue-33387.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-33461.rs b/src/test/ui/issues/issue-33461.rs new file mode 100644 index 00000000000..4e01d4d3061 --- /dev/null +++ b/src/test/ui/issues/issue-33461.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-33498.rs b/src/test/ui/issues/issue-33498.rs new file mode 100644 index 00000000000..9c8a97e7e6b --- /dev/null +++ b/src/test/ui/issues/issue-33498.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +pub fn main() { + let x = (0, 2); + + match x { + (0, ref y) => {} + (y, 0) => {} + _ => (), + } +} diff --git a/src/test/ui/issues/issue-33537.rs b/src/test/ui/issues/issue-33537.rs new file mode 100644 index 00000000000..3539aa64776 --- /dev/null +++ b/src/test/ui/issues/issue-33537.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-33687.rs b/src/test/ui/issues/issue-33687.rs new file mode 100644 index 00000000000..ac802ed86dc --- /dev/null +++ b/src/test/ui/issues/issue-33687.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-33770.rs b/src/test/ui/issues/issue-33770.rs new file mode 100644 index 00000000000..39ae009c996 --- /dev/null +++ b/src/test/ui/issues/issue-33770.rs @@ -0,0 +1,95 @@ +// 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/src/test/ui/issues/issue-3389.rs b/src/test/ui/issues/issue-3389.rs new file mode 100644 index 00000000000..294a07229fb --- /dev/null +++ b/src/test/ui/issues/issue-3389.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-33992.rs b/src/test/ui/issues/issue-33992.rs new file mode 100644 index 00000000000..94fccff9fc6 --- /dev/null +++ b/src/test/ui/issues/issue-33992.rs @@ -0,0 +1,32 @@ +// run-pass +// ignore-windows +// ignore-macos +// ignore-wasm32-bare 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/src/test/ui/issues/issue-34053.rs b/src/test/ui/issues/issue-34053.rs new file mode 100644 index 00000000000..fa23ae8f95b --- /dev/null +++ b/src/test/ui/issues/issue-34053.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-34074.rs b/src/test/ui/issues/issue-34074.rs new file mode 100644 index 00000000000..0600d3937c1 --- /dev/null +++ b/src/test/ui/issues/issue-34074.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-3429.rs b/src/test/ui/issues/issue-3429.rs new file mode 100644 index 00000000000..9d94c3ff61c --- /dev/null +++ b/src/test/ui/issues/issue-3429.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = 1_usize; + let y = || x; + let _z = y(); +} diff --git a/src/test/ui/issues/issue-34427.rs b/src/test/ui/issues/issue-34427.rs new file mode 100644 index 00000000000..a14b5b9e278 --- /dev/null +++ b/src/test/ui/issues/issue-34427.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-3447.rs b/src/test/ui/issues/issue-3447.rs new file mode 100644 index 00000000000..1e329d1522a --- /dev/null +++ b/src/test/ui/issues/issue-3447.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-34503.rs b/src/test/ui/issues/issue-34503.rs new file mode 100644 index 00000000000..26e7358408f --- /dev/null +++ b/src/test/ui/issues/issue-34503.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-34569.rs b/src/test/ui/issues/issue-34569.rs new file mode 100644 index 00000000000..1f68560509e --- /dev/null +++ b/src/test/ui/issues/issue-34569.rs @@ -0,0 +1,17 @@ +// run-pass +// compile-flags:-g + +// 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/src/test/ui/issues/issue-34571.rs b/src/test/ui/issues/issue-34571.rs new file mode 100644 index 00000000000..bad1bebc697 --- /dev/null +++ b/src/test/ui/issues/issue-34571.rs @@ -0,0 +1,11 @@ +// run-pass +#[repr(u8)] +enum Foo { + Foo(u8), +} + +fn main() { + match Foo::Foo(1) { + _ => () + } +} diff --git a/src/test/ui/issues/issue-34784.rs b/src/test/ui/issues/issue-34784.rs new file mode 100644 index 00000000000..d3206e99430 --- /dev/null +++ b/src/test/ui/issues/issue-34784.rs @@ -0,0 +1,19 @@ +// run-pass +#![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/src/test/ui/issues/issue-34796.rs b/src/test/ui/issues/issue-34796.rs new file mode 100644 index 00000000000..88d5c50a27d --- /dev/null +++ b/src/test/ui/issues/issue-34796.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-34798.rs b/src/test/ui/issues/issue-34798.rs new file mode 100644 index 00000000000..f0d710123cd --- /dev/null +++ b/src/test/ui/issues/issue-34798.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-34932.rs b/src/test/ui/issues/issue-34932.rs new file mode 100644 index 00000000000..3a5fd20ebc3 --- /dev/null +++ b/src/test/ui/issues/issue-34932.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags:--test +// rustc-env:RUSTC_BOOTSTRAP_KEY= +#![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/src/test/ui/issues/issue-3500.rs b/src/test/ui/issues/issue-3500.rs new file mode 100644 index 00000000000..7b39cc16cab --- /dev/null +++ b/src/test/ui/issues/issue-3500.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = &Some(1); + match x { + &Some(_) => (), + &None => (), + } +} diff --git a/src/test/ui/issues/issue-35423.rs b/src/test/ui/issues/issue-35423.rs new file mode 100644 index 00000000000..202ffcc1d0d --- /dev/null +++ b/src/test/ui/issues/issue-35423.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-3556.rs b/src/test/ui/issues/issue-3556.rs new file mode 100644 index 00000000000..3c1934ade35 --- /dev/null +++ b/src/test/ui/issues/issue-3556.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-3559.rs b/src/test/ui/issues/issue-3559.rs new file mode 100644 index 00000000000..9d498584a9d --- /dev/null +++ b/src/test/ui/issues/issue-3559.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-35600.rs b/src/test/ui/issues/issue-35600.rs new file mode 100644 index 00000000000..9d74726d279 --- /dev/null +++ b/src/test/ui/issues/issue-35600.rs @@ -0,0 +1,16 @@ +// run-pass +#![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/src/test/ui/issues/issue-3563-3.rs b/src/test/ui/issues/issue-3563-3.rs new file mode 100644 index 00000000000..bedfdab97d5 --- /dev/null +++ b/src/test/ui/issues/issue-3563-3.rs @@ -0,0 +1,180 @@ +// 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/src/test/ui/issues/issue-3574.rs b/src/test/ui/issues/issue-3574.rs new file mode 100644 index 00000000000..eb967577ffb --- /dev/null +++ b/src/test/ui/issues/issue-3574.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-35815.rs b/src/test/ui/issues/issue-35815.rs new file mode 100644 index 00000000000..05fd1b15d43 --- /dev/null +++ b/src/test/ui/issues/issue-35815.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-36023.rs b/src/test/ui/issues/issue-36023.rs new file mode 100644 index 00000000000..64d92bf8c3c --- /dev/null +++ b/src/test/ui/issues/issue-36023.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-36036-associated-type-layout.rs b/src/test/ui/issues/issue-36036-associated-type-layout.rs new file mode 100644 index 00000000000..022f9a5d556 --- /dev/null +++ b/src/test/ui/issues/issue-36036-associated-type-layout.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-36053.rs b/src/test/ui/issues/issue-36053.rs new file mode 100644 index 00000000000..a61c02c0a12 --- /dev/null +++ b/src/test/ui/issues/issue-36053.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-36139-normalize-closure-sig.rs b/src/test/ui/issues/issue-36139-normalize-closure-sig.rs new file mode 100644 index 00000000000..2d49151ffcc --- /dev/null +++ b/src/test/ui/issues/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-36260.rs b/src/test/ui/issues/issue-36260.rs new file mode 100644 index 00000000000..d96dc80ea71 --- /dev/null +++ b/src/test/ui/issues/issue-36260.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-36278-prefix-nesting.rs b/src/test/ui/issues/issue-36278-prefix-nesting.rs new file mode 100644 index 00000000000..62d1f5f8258 --- /dev/null +++ b/src/test/ui/issues/issue-36278-prefix-nesting.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-36381.rs b/src/test/ui/issues/issue-36381.rs new file mode 100644 index 00000000000..7db56f1dce8 --- /dev/null +++ b/src/test/ui/issues/issue-36381.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-36401.rs b/src/test/ui/issues/issue-36401.rs new file mode 100644 index 00000000000..f51197b01c7 --- /dev/null +++ b/src/test/ui/issues/issue-36401.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-36474.rs b/src/test/ui/issues/issue-36474.rs new file mode 100644 index 00000000000..90ee5b3cd4b --- /dev/null +++ b/src/test/ui/issues/issue-36474.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-3656.rs b/src/test/ui/issues/issue-3656.rs new file mode 100644 index 00000000000..d55a22a72b6 --- /dev/null +++ b/src/test/ui/issues/issue-3656.rs @@ -0,0 +1,30 @@ +// 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, uint32_t, c_void}; + +pub struct KEYGEN { + hash_algorithm: [c_uint; 2], + count: uint32_t, + salt: *const c_void, + salt_size: uint32_t, +} + +extern { + // Bogus signature, just need to test if it compiles. + pub fn malloc(data: KEYGEN); +} + +pub fn main() { +} diff --git a/src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs b/src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs new file mode 100644 index 00000000000..34bbb66d979 --- /dev/null +++ b/src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-36768.rs b/src/test/ui/issues/issue-36768.rs new file mode 100644 index 00000000000..f671cbc8205 --- /dev/null +++ b/src/test/ui/issues/issue-36768.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags:--test +#![deny(private_in_public)] + +#[test] fn foo() {} +mod foo {} + +#[test] fn core() {} +extern crate core; diff --git a/src/test/ui/issues/issue-36786-resolve-call.rs b/src/test/ui/issues/issue-36786-resolve-call.rs new file mode 100644 index 00000000000..e5341ba7dbe --- /dev/null +++ b/src/test/ui/issues/issue-36786-resolve-call.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-36792.rs b/src/test/ui/issues/issue-36792.rs new file mode 100644 index 00000000000..99ae633dd0e --- /dev/null +++ b/src/test/ui/issues/issue-36792.rs @@ -0,0 +1,7 @@ +// run-pass +fn foo() -> impl Copy { + foo +} +fn main() { + foo(); +} diff --git a/src/test/ui/issues/issue-36816.rs b/src/test/ui/issues/issue-36816.rs new file mode 100644 index 00000000000..54690b43c46 --- /dev/null +++ b/src/test/ui/issues/issue-36816.rs @@ -0,0 +1,7 @@ +// run-pass +macro_rules! m { () => { 1 } } +macro_rules! n { () => { 1 + m!() } } + +fn main() { + let _: [u32; n!()] = [0, 0]; +} diff --git a/src/test/ui/issues/issue-3683.rs b/src/test/ui/issues/issue-3683.rs new file mode 100644 index 00000000000..b12c450c937 --- /dev/null +++ b/src/test/ui/issues/issue-3683.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-36856.rs b/src/test/ui/issues/issue-36856.rs new file mode 100644 index 00000000000..f2dfaf3dd36 --- /dev/null +++ b/src/test/ui/issues/issue-36856.rs @@ -0,0 +1,15 @@ +// run-pass +// Regression test for #36856. + +// compile-flags:-g + +fn g() -> bool { + false +} + +pub fn main() { + let a = !g(); + if a != !g() { + panic!(); + } +} diff --git a/src/test/ui/issues/issue-36936.rs b/src/test/ui/issues/issue-36936.rs new file mode 100644 index 00000000000..486a422b754 --- /dev/null +++ b/src/test/ui/issues/issue-36936.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-36954.rs b/src/test/ui/issues/issue-36954.rs new file mode 100644 index 00000000000..56ff9926ef1 --- /dev/null +++ b/src/test/ui/issues/issue-36954.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-36954.rs + +extern crate issue_36954 as lib; + +fn main() { + let _ = lib::FOO; +} diff --git a/src/test/ui/issues/issue-3702.rs b/src/test/ui/issues/issue-3702.rs new file mode 100644 index 00000000000..f48d549b3eb --- /dev/null +++ b/src/test/ui/issues/issue-3702.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-37109.rs b/src/test/ui/issues/issue-37109.rs new file mode 100644 index 00000000000..1e57d5f95e8 --- /dev/null +++ b/src/test/ui/issues/issue-37109.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-37175.rs b/src/test/ui/issues/issue-37175.rs new file mode 100644 index 00000000000..9ec9d48d18b --- /dev/null +++ b/src/test/ui/issues/issue-37175.rs @@ -0,0 +1,5 @@ +// run-pass +macro_rules! m { (<$t:ty>) => { stringify!($t) } } +fn main() { + println!("{}", m!(>)); +} diff --git a/src/test/ui/issues/issue-37222.rs b/src/test/ui/issues/issue-37222.rs new file mode 100644 index 00000000000..8ea5f6b7a27 --- /dev/null +++ b/src/test/ui/issues/issue-37222.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-37291/auxiliary/lib.rs b/src/test/ui/issues/issue-37291/auxiliary/lib.rs new file mode 100644 index 00000000000..1b163ee1391 --- /dev/null +++ b/src/test/ui/issues/issue-37291/auxiliary/lib.rs @@ -0,0 +1,42 @@ +#![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/src/test/ui/issues/issue-37291/main.rs b/src/test/ui/issues/issue-37291/main.rs new file mode 100644 index 00000000000..6fb6b50da20 --- /dev/null +++ b/src/test/ui/issues/issue-37291/main.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-3743.rs b/src/test/ui/issues/issue-3743.rs new file mode 100644 index 00000000000..07741914f80 --- /dev/null +++ b/src/test/ui/issues/issue-3743.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/issues/issue-3753.rs b/src/test/ui/issues/issue-3753.rs new file mode 100644 index 00000000000..dc9e42bad97 --- /dev/null +++ b/src/test/ui/issues/issue-3753.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-37686.rs b/src/test/ui/issues/issue-37686.rs new file mode 100644 index 00000000000..8c376251449 --- /dev/null +++ b/src/test/ui/issues/issue-37686.rs @@ -0,0 +1,7 @@ +// run-pass +fn main() { + match (0, 0) { + (std::usize::MIN, std::usize::MAX) => {} + _ => {} + } +} diff --git a/src/test/ui/issues/issue-3794.rs b/src/test/ui/issues/issue-3794.rs new file mode 100644 index 00000000000..408d8d866d8 --- /dev/null +++ b/src/test/ui/issues/issue-3794.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-37991.rs b/src/test/ui/issues/issue-37991.rs new file mode 100644 index 00000000000..a6ac4d5ca2e --- /dev/null +++ b/src/test/ui/issues/issue-37991.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-38002.rs b/src/test/ui/issues/issue-38002.rs new file mode 100644 index 00000000000..fdb31fc44a1 --- /dev/null +++ b/src/test/ui/issues/issue-38002.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/issues/issue-38033.rs b/src/test/ui/issues/issue-38033.rs new file mode 100644 index 00000000000..16b867ec88f --- /dev/null +++ b/src/test/ui/issues/issue-38033.rs @@ -0,0 +1,79 @@ +// 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/src/test/ui/issues/issue-38074.rs b/src/test/ui/issues/issue-38074.rs new file mode 100644 index 00000000000..214d6752cef --- /dev/null +++ b/src/test/ui/issues/issue-38074.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-38091.rs b/src/test/ui/issues/issue-38091.rs new file mode 100644 index 00000000000..00aa810f830 --- /dev/null +++ b/src/test/ui/issues/issue-38091.rs @@ -0,0 +1,20 @@ +// run-pass +#![feature(specialization)] + +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 {} + +fn main() { + Iterate::iterate(0); +} diff --git a/src/test/ui/issues/issue-38190.rs b/src/test/ui/issues/issue-38190.rs new file mode 100644 index 00000000000..cfa0420c80d --- /dev/null +++ b/src/test/ui/issues/issue-38190.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-38226.rs b/src/test/ui/issues/issue-38226.rs new file mode 100644 index 00000000000..3213e3618a8 --- /dev/null +++ b/src/test/ui/issues/issue-38226.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-38437.rs b/src/test/ui/issues/issue-38437.rs new file mode 100644 index 00000000000..e1412169065 --- /dev/null +++ b/src/test/ui/issues/issue-38437.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-3847.rs b/src/test/ui/issues/issue-3847.rs new file mode 100644 index 00000000000..16e0b00b39a --- /dev/null +++ b/src/test/ui/issues/issue-3847.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-38556.rs b/src/test/ui/issues/issue-38556.rs new file mode 100644 index 00000000000..63fd9db08ff --- /dev/null +++ b/src/test/ui/issues/issue-38556.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +pub struct Foo; + +macro_rules! reexport { + () => { use Foo as Bar; } +} + +reexport!(); + +fn main() { + fn f(_: Bar) {} +} diff --git a/src/test/ui/issues/issue-38763.rs b/src/test/ui/issues/issue-38763.rs new file mode 100644 index 00000000000..6e6de09225f --- /dev/null +++ b/src/test/ui/issues/issue-38763.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-emscripten + +#[repr(C)] +pub struct Foo(i128); + +#[no_mangle] +pub extern "C" fn foo(x: Foo) -> Foo { x } + +fn main() { + foo(Foo(1)); +} diff --git a/src/test/ui/issues/issue-3878.rs b/src/test/ui/issues/issue-3878.rs new file mode 100644 index 00000000000..a121f0ba878 --- /dev/null +++ b/src/test/ui/issues/issue-3878.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(path_statements)] +#![feature(box_syntax)] + +pub fn main() { + let y: Box<_> = box 1; + y; +} diff --git a/src/test/ui/issues/issue-38942.rs b/src/test/ui/issues/issue-38942.rs new file mode 100644 index 00000000000..308bdd6e28c --- /dev/null +++ b/src/test/ui/issues/issue-38942.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-3895.rs b/src/test/ui/issues/issue-3895.rs new file mode 100644 index 00000000000..c560ca60dd3 --- /dev/null +++ b/src/test/ui/issues/issue-3895.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-38987.rs b/src/test/ui/issues/issue-38987.rs new file mode 100644 index 00000000000..cb4e1b0d409 --- /dev/null +++ b/src/test/ui/issues/issue-38987.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; +} diff --git a/src/test/ui/issues/issue-3904.rs b/src/test/ui/issues/issue-3904.rs new file mode 100644 index 00000000000..7beb91a28d2 --- /dev/null +++ b/src/test/ui/issues/issue-3904.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-39292.rs b/src/test/ui/issues/issue-39292.rs new file mode 100644 index 00000000000..968cf08916f --- /dev/null +++ b/src/test/ui/issues/issue-39292.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-3935.rs b/src/test/ui/issues/issue-3935.rs new file mode 100644 index 00000000000..e98d68e0eb2 --- /dev/null +++ b/src/test/ui/issues/issue-3935.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-39367.rs b/src/test/ui/issues/issue-39367.rs new file mode 100644 index 00000000000..8314be3d14c --- /dev/null +++ b/src/test/ui/issues/issue-39367.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/issues/issue-39548.rs b/src/test/ui/issues/issue-39548.rs new file mode 100644 index 00000000000..304e37bf3d6 --- /dev/null +++ b/src/test/ui/issues/issue-39548.rs @@ -0,0 +1,6 @@ +// run-pass +type Array = [(); ((1 < 2) == false) as usize]; + +fn main() { + let _: Array = []; +} diff --git a/src/test/ui/issues/issue-39709.rs b/src/test/ui/issues/issue-39709.rs new file mode 100644 index 00000000000..69ef2700ef3 --- /dev/null +++ b/src/test/ui/issues/issue-39709.rs @@ -0,0 +1,5 @@ +// run-pass +#![allow(unused_macros)] +fn main() { + println!("{}", { macro_rules! x { ($(t:tt)*) => {} } 33 }); +} diff --git a/src/test/ui/issues/issue-39720.rs b/src/test/ui/issues/issue-39720.rs new file mode 100644 index 00000000000..a3baa361d57 --- /dev/null +++ b/src/test/ui/issues/issue-39720.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(non_snake_case)] + +// ignore-emscripten FIXME(#45351) + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(C)] +#[repr(simd)] +#[derive(Copy, Clone, Debug)] +pub struct char3(pub i8, pub i8, pub i8); + +#[repr(C)] +#[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/src/test/ui/issues/issue-39720.stderr b/src/test/ui/issues/issue-39720.stderr new file mode 100644 index 00000000000..8121ed28940 --- /dev/null +++ b/src/test/ui/issues/issue-39720.stderr @@ -0,0 +1,16 @@ +warning[E0566]: conflicting representation hints + --> $DIR/issue-39720.rs:8:8 + | +LL | #[repr(C)] + | ^ +LL | #[repr(simd)] + | ^^^^ + +warning[E0566]: conflicting representation hints + --> $DIR/issue-39720.rs:13:8 + | +LL | #[repr(C)] + | ^ +LL | #[repr(simd)] + | ^^^^ + diff --git a/src/test/ui/issues/issue-3979-generics.rs b/src/test/ui/issues/issue-3979-generics.rs new file mode 100644 index 00000000000..519de1cad6e --- /dev/null +++ b/src/test/ui/issues/issue-3979-generics.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/issues/issue-3979-xcrate.rs b/src/test/ui/issues/issue-3979-xcrate.rs new file mode 100644 index 00000000000..fcb1f55c32f --- /dev/null +++ b/src/test/ui/issues/issue-3979-xcrate.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-3979.rs b/src/test/ui/issues/issue-3979.rs new file mode 100644 index 00000000000..72949d8c757 --- /dev/null +++ b/src/test/ui/issues/issue-3979.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-39808.rs b/src/test/ui/issues/issue-39808.rs new file mode 100644 index 00000000000..a4701367373 --- /dev/null +++ b/src/test/ui/issues/issue-39808.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-39823.rs b/src/test/ui/issues/issue-39823.rs new file mode 100644 index 00000000000..148cf527e7c --- /dev/null +++ b/src/test/ui/issues/issue-39823.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-39827.rs b/src/test/ui/issues/issue-39827.rs new file mode 100644 index 00000000000..782c668c843 --- /dev/null +++ b/src/test/ui/issues/issue-39827.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-40003.rs b/src/test/ui/issues/issue-40003.rs new file mode 100644 index 00000000000..642de6b8fe3 --- /dev/null +++ b/src/test/ui/issues/issue-40003.rs @@ -0,0 +1,178 @@ +// 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/src/test/ui/issues/issue-40085.rs b/src/test/ui/issues/issue-40085.rs new file mode 100644 index 00000000000..132044cfd6d --- /dev/null +++ b/src/test/ui/issues/issue-40085.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-40235.rs b/src/test/ui/issues/issue-40235.rs new file mode 100644 index 00000000000..0f799c3503f --- /dev/null +++ b/src/test/ui/issues/issue-40235.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_variables)] +fn foo() {} + +fn main() { + while let Some(foo) = Some(1) { break } + foo(); +} diff --git a/src/test/ui/issues/issue-40408.rs b/src/test/ui/issues/issue-40408.rs new file mode 100644 index 00000000000..81acc41cb83 --- /dev/null +++ b/src/test/ui/issues/issue-40408.rs @@ -0,0 +1,7 @@ +// run-pass +fn main() { + println!("{}", 0E+10); + println!("{}", 0e+10); + println!("{}", 00e+10); + println!("{}", 00E+10); +} diff --git a/src/test/ui/issues/issue-40469.rs b/src/test/ui/issues/issue-40469.rs new file mode 100644 index 00000000000..25e08ef85e9 --- /dev/null +++ b/src/test/ui/issues/issue-40469.rs @@ -0,0 +1,9 @@ +// run-pass +// ignore-pretty issue #37195 + +#![allow(dead_code)] + +include!("auxiliary/issue-40469.rs"); +fn f() { m!(); } + +fn main() {} diff --git a/src/test/ui/issues/issue-40770.rs b/src/test/ui/issues/issue-40770.rs new file mode 100644 index 00000000000..c9713c15798 --- /dev/null +++ b/src/test/ui/issues/issue-40770.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_macros)] +macro_rules! m { + ($e:expr) => { + macro_rules! n { () => { $e } } + } +} + +fn main() { + m!(foo!()); +} diff --git a/src/test/ui/issues/issue-40847.rs b/src/test/ui/issues/issue-40847.rs new file mode 100644 index 00000000000..087b40ad6cd --- /dev/null +++ b/src/test/ui/issues/issue-40847.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-40883.rs b/src/test/ui/issues/issue-40883.rs new file mode 100644 index 00000000000..37e61b1b0e6 --- /dev/null +++ b/src/test/ui/issues/issue-40883.rs @@ -0,0 +1,93 @@ +// 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` + 128 "misc" bytes. + if stack_usage > mem::size_of::() * 2 + 128 { + 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/src/test/ui/issues/issue-40951.rs b/src/test/ui/issues/issue-40951.rs new file mode 100644 index 00000000000..49171eba6b3 --- /dev/null +++ b/src/test/ui/issues/issue-40951.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-41053.rs b/src/test/ui/issues/issue-41053.rs new file mode 100644 index 00000000000..967edfd4415 --- /dev/null +++ b/src/test/ui/issues/issue-41053.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-4107.rs b/src/test/ui/issues/issue-4107.rs new file mode 100644 index 00000000000..98433e806e3 --- /dev/null +++ b/src/test/ui/issues/issue-4107.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-41213.rs b/src/test/ui/issues/issue-41213.rs new file mode 100644 index 00000000000..5c91bf71102 --- /dev/null +++ b/src/test/ui/issues/issue-41213.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-41479.rs b/src/test/ui/issues/issue-41479.rs new file mode 100644 index 00000000000..6daaf440e4b --- /dev/null +++ b/src/test/ui/issues/issue-41479.rs @@ -0,0 +1,9 @@ +// run-pass +fn split(pair: (A, B)) { + let _a = pair.0; + let _b = pair.1; +} + +fn main() { + split(((), ((), ()))); +} diff --git a/src/test/ui/issues/issue-41498.rs b/src/test/ui/issues/issue-41498.rs new file mode 100644 index 00000000000..ad918ecddeb --- /dev/null +++ b/src/test/ui/issues/issue-41498.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-41604.rs b/src/test/ui/issues/issue-41604.rs new file mode 100644 index 00000000000..11a1cc25b71 --- /dev/null +++ b/src/test/ui/issues/issue-41604.rs @@ -0,0 +1,11 @@ +// run-pass +struct B; + +impl B { + fn init(&mut self) {} +} + +fn main() { + let mut b = [B]; + b[1-1].init(); +} diff --git a/src/test/ui/issues/issue-41677.rs b/src/test/ui/issues/issue-41677.rs new file mode 100644 index 00000000000..afddbc799b7 --- /dev/null +++ b/src/test/ui/issues/issue-41677.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-41696.rs b/src/test/ui/issues/issue-41696.rs new file mode 100644 index 00000000000..d094f71942f --- /dev/null +++ b/src/test/ui/issues/issue-41696.rs @@ -0,0 +1,54 @@ +// 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/src/test/ui/issues/issue-41744.rs b/src/test/ui/issues/issue-41744.rs new file mode 100644 index 00000000000..dcdd1c21ee5 --- /dev/null +++ b/src/test/ui/issues/issue-41744.rs @@ -0,0 +1,7 @@ +// run-pass +trait Tc {} +impl Tc for bool {} + +fn main() { + let _: &[&dyn Tc] = &[&true]; +} diff --git a/src/test/ui/issues/issue-41803.rs b/src/test/ui/issues/issue-41803.rs new file mode 100644 index 00000000000..19ab81d04d0 --- /dev/null +++ b/src/test/ui/issues/issue-41803.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-41849-variance-req.rs b/src/test/ui/issues/issue-41849-variance-req.rs new file mode 100644 index 00000000000..af081083a35 --- /dev/null +++ b/src/test/ui/issues/issue-41849-variance-req.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/issues/issue-41888.rs b/src/test/ui/issues/issue-41888.rs new file mode 100644 index 00000000000..32df520f279 --- /dev/null +++ b/src/test/ui/issues/issue-41888.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-42007.rs b/src/test/ui/issues/issue-42007.rs new file mode 100644 index 00000000000..a477e476eb9 --- /dev/null +++ b/src/test/ui/issues/issue-42007.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-4208.rs b/src/test/ui/issues/issue-4208.rs new file mode 100644 index 00000000000..3b01811a9e8 --- /dev/null +++ b/src/test/ui/issues/issue-4208.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-42148.rs b/src/test/ui/issues/issue-42148.rs new file mode 100644 index 00000000000..cb8c0d6edb6 --- /dev/null +++ b/src/test/ui/issues/issue-42148.rs @@ -0,0 +1,6 @@ +// run-pass +struct Zst; + +fn main() { + unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) } +} diff --git a/src/test/ui/issues/issue-42210.rs b/src/test/ui/issues/issue-42210.rs new file mode 100644 index 00000000000..318e3099f98 --- /dev/null +++ b/src/test/ui/issues/issue-42210.rs @@ -0,0 +1,20 @@ +// run-pass +// Regression test for #42210. + +// compile-flags: -g + +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/src/test/ui/issues/issue-4228.rs b/src/test/ui/issues/issue-4228.rs new file mode 100644 index 00000000000..491000b6510 --- /dev/null +++ b/src/test/ui/issues/issue-4228.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-42453.rs b/src/test/ui/issues/issue-42453.rs new file mode 100644 index 00000000000..92fefceabc1 --- /dev/null +++ b/src/test/ui/issues/issue-42453.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Debug)] +struct builder; + +fn main() { + +} diff --git a/src/test/ui/issues/issue-42463.rs b/src/test/ui/issues/issue-42463.rs new file mode 100644 index 00000000000..51d6ea3f7a8 --- /dev/null +++ b/src/test/ui/issues/issue-42463.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-4252.rs b/src/test/ui/issues/issue-4252.rs new file mode 100644 index 00000000000..48e617fd7eb --- /dev/null +++ b/src/test/ui/issues/issue-4252.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-42552.rs b/src/test/ui/issues/issue-42552.rs new file mode 100644 index 00000000000..50d28a2f0c6 --- /dev/null +++ b/src/test/ui/issues/issue-42552.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/issues/issue-42679.rs b/src/test/ui/issues/issue-42679.rs new file mode 100644 index 00000000000..596309f2568 --- /dev/null +++ b/src/test/ui/issues/issue-42679.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-42747.rs b/src/test/ui/issues/issue-42747.rs new file mode 100644 index 00000000000..fec65878210 --- /dev/null +++ b/src/test/ui/issues/issue-42747.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-43132.rs b/src/test/ui/issues/issue-43132.rs new file mode 100644 index 00000000000..c886f4b0a2d --- /dev/null +++ b/src/test/ui/issues/issue-43132.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/issues/issue-43205.rs b/src/test/ui/issues/issue-43205.rs new file mode 100644 index 00000000000..894a61f3eff --- /dev/null +++ b/src/test/ui/issues/issue-43205.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + &&[()][0]; + println!("{:?}", &[(),()][1]); +} diff --git a/src/test/ui/issues/issue-43291.rs b/src/test/ui/issues/issue-43291.rs new file mode 100644 index 00000000000..52b629e35c8 --- /dev/null +++ b/src/test/ui/issues/issue-43291.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-4333.rs b/src/test/ui/issues/issue-4333.rs new file mode 100644 index 00000000000..3df319b683f --- /dev/null +++ b/src/test/ui/issues/issue-4333.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-43692.rs b/src/test/ui/issues/issue-43692.rs new file mode 100644 index 00000000000..a9999c22651 --- /dev/null +++ b/src/test/ui/issues/issue-43692.rs @@ -0,0 +1,5 @@ +// 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/src/test/ui/issues/issue-43853.rs b/src/test/ui/issues/issue-43853.rs new file mode 100644 index 00000000000..47c3ab59aa2 --- /dev/null +++ b/src/test/ui/issues/issue-43853.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-4387.rs b/src/test/ui/issues/issue-4387.rs new file mode 100644 index 00000000000..84592f16a4c --- /dev/null +++ b/src/test/ui/issues/issue-4387.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let _foo = [0; 2*4]; +} diff --git a/src/test/ui/issues/issue-43910.rs b/src/test/ui/issues/issue-43910.rs new file mode 100644 index 00000000000..d8c87732930 --- /dev/null +++ b/src/test/ui/issues/issue-43910.rs @@ -0,0 +1,7 @@ +// run-pass +#![deny(unused_variables)] + +fn main() { + #[allow(unused_variables)] + let x = 12; +} diff --git a/src/test/ui/issues/issue-43923.rs b/src/test/ui/issues/issue-43923.rs new file mode 100644 index 00000000000..ad35a668554 --- /dev/null +++ b/src/test/ui/issues/issue-43923.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-4401.rs b/src/test/ui/issues/issue-4401.rs new file mode 100644 index 00000000000..fef73fbe1f5 --- /dev/null +++ b/src/test/ui/issues/issue-4401.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-44333.rs b/src/test/ui/issues/issue-44333.rs new file mode 100644 index 00000000000..fffef975043 --- /dev/null +++ b/src/test/ui/issues/issue-44333.rs @@ -0,0 +1,20 @@ +// run-pass +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"), + BAR => println!("bar"), + _ => unreachable!(), + } +} diff --git a/src/test/ui/issues/issue-4446.rs b/src/test/ui/issues/issue-4446.rs new file mode 100644 index 00000000000..948f2a7bdf3 --- /dev/null +++ b/src/test/ui/issues/issue-4446.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-4448.rs b/src/test/ui/issues/issue-4448.rs new file mode 100644 index 00000000000..27d0326891b --- /dev/null +++ b/src/test/ui/issues/issue-4448.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::<&'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/src/test/ui/issues/issue-45124.rs b/src/test/ui/issues/issue-45124.rs new file mode 100644 index 00000000000..942014c9184 --- /dev/null +++ b/src/test/ui/issues/issue-45124.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-45152.rs b/src/test/ui/issues/issue-45152.rs new file mode 100644 index 00000000000..fb1c9fb78f3 --- /dev/null +++ b/src/test/ui/issues/issue-45152.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-4541.rs b/src/test/ui/issues/issue-4541.rs new file mode 100644 index 00000000000..1f871fcf613 --- /dev/null +++ b/src/test/ui/issues/issue-4541.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-4542.rs b/src/test/ui/issues/issue-4542.rs new file mode 100644 index 00000000000..24752114e9f --- /dev/null +++ b/src/test/ui/issues/issue-4542.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-4545.rs b/src/test/ui/issues/issue-4545.rs new file mode 100644 index 00000000000..86fcf9af21f --- /dev/null +++ b/src/test/ui/issues/issue-4545.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/issues/issue-45510.rs b/src/test/ui/issues/issue-45510.rs new file mode 100644 index 00000000000..9e104ce6c4f --- /dev/null +++ b/src/test/ui/issues/issue-45510.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-45731.rs b/src/test/ui/issues/issue-45731.rs new file mode 100644 index 00000000000..d20c07276a8 --- /dev/null +++ b/src/test/ui/issues/issue-45731.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags:--test -g + +#[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/src/test/ui/issues/issue-46069.rs b/src/test/ui/issues/issue-46069.rs new file mode 100644 index 00000000000..1d4f789828d --- /dev/null +++ b/src/test/ui/issues/issue-46069.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-46095.rs b/src/test/ui/issues/issue-46095.rs new file mode 100644 index 00000000000..59ddb60c9f2 --- /dev/null +++ b/src/test/ui/issues/issue-46095.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-46519.rs b/src/test/ui/issues/issue-46519.rs new file mode 100644 index 00000000000..461ea2498b0 --- /dev/null +++ b/src/test/ui/issues/issue-46519.rs @@ -0,0 +1,28 @@ +// run-pass +// compile-flags:--test -O + +#[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/src/test/ui/issues/issue-46553.rs b/src/test/ui/issues/issue-46553.rs new file mode 100644 index 00000000000..e21a532effd --- /dev/null +++ b/src/test/ui/issues/issue-46553.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(const_fn)] +#![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/src/test/ui/issues/issue-46845.rs b/src/test/ui/issues/issue-46845.rs new file mode 100644 index 00000000000..fc85b25519a --- /dev/null +++ b/src/test/ui/issues/issue-46845.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-46855.rs b/src/test/ui/issues/issue-46855.rs new file mode 100644 index 00000000000..aa6378f8594 --- /dev/null +++ b/src/test/ui/issues/issue-46855.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-46920-byte-array-patterns.rs b/src/test/ui/issues/issue-46920-byte-array-patterns.rs new file mode 100644 index 00000000000..2a8b4bb4922 --- /dev/null +++ b/src/test/ui/issues/issue-46920-byte-array-patterns.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-47139-1.rs b/src/test/ui/issues/issue-47139-1.rs new file mode 100644 index 00000000000..c55fc34346c --- /dev/null +++ b/src/test/ui/issues/issue-47139-1.rs @@ -0,0 +1,78 @@ +// run-pass +// Regression test for issue #47139: +// +// Coherence was encountering an (unnecessary) overflow trying to +// decide if the two impls of dummy overlap. +// +// The overflow went something like: +// +// - `&'a ?T: Insertable` ? +// - let ?T = Option ? +// - `Option: Insertable` ? +// - `Option<&'a ?U>: Insertable` ? +// - `&'a ?U: Insertable` ? +// +// While somewhere in the middle, a projection would occur, which +// broke cycle detection. +// +// It turned out that this cycle was being kicked off due to some +// extended diagnostic attempts in coherence, so removing those +// sidestepped the issue for now. + +#![allow(dead_code)] + +pub trait Insertable { + type Values; + + fn values(self) -> Self::Values; +} + +impl Insertable for Option + where + T: Insertable, + T::Values: Default, +{ + type Values = T::Values; + + fn values(self) -> Self::Values { + self.map(Insertable::values).unwrap_or_default() + } +} + +impl<'a, T> Insertable for &'a Option + where + Option<&'a T>: Insertable, +{ + type Values = as Insertable>::Values; + + fn values(self) -> Self::Values { + self.as_ref().values() + } +} + +impl<'a, T> Insertable for &'a [T] +{ + type Values = Self; + + fn values(self) -> Self::Values { + self + } +} + +trait Unimplemented { } + +trait Dummy { } + +struct Foo { t: T } + +impl<'a, U> Dummy for Foo<&'a U> + where &'a U: Insertable +{ +} + +impl Dummy for T + where T: Unimplemented +{ } + +fn main() { +} diff --git a/src/test/ui/issues/issue-47139-2.rs b/src/test/ui/issues/issue-47139-2.rs new file mode 100644 index 00000000000..d2ef8942530 --- /dev/null +++ b/src/test/ui/issues/issue-47139-2.rs @@ -0,0 +1,66 @@ +// run-pass +// Regression test for issue #47139: +// +// Same as issue-47139-1.rs, but the impls of dummy are in the +// opposite order. This influenced the way that coherence ran and in +// some cases caused the overflow to occur when it wouldn't otherwise. +// In an effort to make the regr test more robust, I am including both +// orderings. + +#![allow(dead_code)] + +pub trait Insertable { + type Values; + + fn values(self) -> Self::Values; +} + +impl Insertable for Option + where + T: Insertable, + T::Values: Default, +{ + type Values = T::Values; + + fn values(self) -> Self::Values { + self.map(Insertable::values).unwrap_or_default() + } +} + +impl<'a, T> Insertable for &'a Option + where + Option<&'a T>: Insertable, +{ + type Values = as Insertable>::Values; + + fn values(self) -> Self::Values { + self.as_ref().values() + } +} + +impl<'a, T> Insertable for &'a [T] +{ + type Values = Self; + + fn values(self) -> Self::Values { + self + } +} + +trait Unimplemented { } + +trait Dummy { } + +struct Foo { t: T } + +impl Dummy for T + where T: Unimplemented +{ } + +impl<'a, U> Dummy for Foo<&'a U> + where &'a U: Insertable +{ +} + +fn main() { +} diff --git a/src/test/ui/issues/issue-4734.rs b/src/test/ui/issues/issue-4734.rs new file mode 100644 index 00000000000..29c965d7ff5 --- /dev/null +++ b/src/test/ui/issues/issue-4734.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/issues/issue-4735.rs b/src/test/ui/issues/issue-4735.rs new file mode 100644 index 00000000000..3ea4b01cd2b --- /dev/null +++ b/src/test/ui/issues/issue-4735.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-47364.rs b/src/test/ui/issues/issue-47364.rs new file mode 100644 index 00000000000..b524354d9a1 --- /dev/null +++ b/src/test/ui/issues/issue-47364.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/issues/issue-4759-1.rs b/src/test/ui/issues/issue-4759-1.rs new file mode 100644 index 00000000000..96fae0fecd9 --- /dev/null +++ b/src/test/ui/issues/issue-4759-1.rs @@ -0,0 +1,4 @@ +// run-pass +trait U { fn f(self); } +impl U for isize { fn f(self) {} } +pub fn main() { 4.f(); } diff --git a/src/test/ui/issues/issue-4759.rs b/src/test/ui/issues/issue-4759.rs new file mode 100644 index 00000000000..53785af0962 --- /dev/null +++ b/src/test/ui/issues/issue-4759.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-47638.rs b/src/test/ui/issues/issue-47638.rs new file mode 100644 index 00000000000..a1ed3c36544 --- /dev/null +++ b/src/test/ui/issues/issue-47638.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-48006.rs b/src/test/ui/issues/issue-48006.rs new file mode 100644 index 00000000000..3a862ace55e --- /dev/null +++ b/src/test/ui/issues/issue-48006.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-48159.rs b/src/test/ui/issues/issue-48159.rs new file mode 100644 index 00000000000..fc8f31fb1ef --- /dev/null +++ b/src/test/ui/issues/issue-48159.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-48508-aux.rs b/src/test/ui/issues/issue-48508-aux.rs new file mode 100644 index 00000000000..ebdc70a04df --- /dev/null +++ b/src/test/ui/issues/issue-48508-aux.rs @@ -0,0 +1,7 @@ +// run-pass +// ignore-test Not a test. Used by issue-48508.rs + +pub fn other() -> f64 { + let µ = 1.0; + µ +} diff --git a/src/test/ui/issues/issue-48508.rs b/src/test/ui/issues/issue-48508.rs new file mode 100644 index 00000000000..385192b882b --- /dev/null +++ b/src/test/ui/issues/issue-48508.rs @@ -0,0 +1,19 @@ +// 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 + +#![feature(non_ascii_idents)] + +#[path = "issue-48508-aux.rs"] +mod other_file; + +fn main() { + other_file::other(); +} diff --git a/src/test/ui/issues/issue-4865-1.rs b/src/test/ui/issues/issue-4865-1.rs new file mode 100644 index 00000000000..68fbee37d01 --- /dev/null +++ b/src/test/ui/issues/issue-4865-1.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/issues/issue-4865-2.rs b/src/test/ui/issues/issue-4865-2.rs new file mode 100644 index 00000000000..cbe1d0d32c6 --- /dev/null +++ b/src/test/ui/issues/issue-4865-2.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-4865-3.rs b/src/test/ui/issues/issue-4865-3.rs new file mode 100644 index 00000000000..12f9bba18d8 --- /dev/null +++ b/src/test/ui/issues/issue-4865-3.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-4875.rs b/src/test/ui/issues/issue-4875.rs new file mode 100644 index 00000000000..8d361314f73 --- /dev/null +++ b/src/test/ui/issues/issue-4875.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-48962.rs b/src/test/ui/issues/issue-48962.rs new file mode 100644 index 00000000000..80d815379be --- /dev/null +++ b/src/test/ui/issues/issue-48962.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-48984.rs b/src/test/ui/issues/issue-48984.rs new file mode 100644 index 00000000000..cb340f84897 --- /dev/null +++ b/src/test/ui/issues/issue-48984.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-49298.rs b/src/test/ui/issues/issue-49298.rs new file mode 100644 index 00000000000..697a160b4ec --- /dev/null +++ b/src/test/ui/issues/issue-49298.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs new file mode 100644 index 00000000000..f30d7e2edcc --- /dev/null +++ b/src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-49632.rs b/src/test/ui/issues/issue-49632.rs new file mode 100644 index 00000000000..155fd0d24eb --- /dev/null +++ b/src/test/ui/issues/issue-49632.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(stmt_expr_attributes)] + +pub fn main() { + let _x = #[inline(always)] || {}; + let _y = #[inline(never)] || {}; + let _z = #[inline] || {}; +} diff --git a/src/test/ui/issues/issue-49685.rs b/src/test/ui/issues/issue-49685.rs new file mode 100644 index 00000000000..fb328d67b75 --- /dev/null +++ b/src/test/ui/issues/issue-49685.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-49854.rs b/src/test/ui/issues/issue-49854.rs new file mode 100644 index 00000000000..0e1db00a34c --- /dev/null +++ b/src/test/ui/issues/issue-49854.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-49955-2.rs b/src/test/ui/issues/issue-49955-2.rs new file mode 100644 index 00000000000..267ed746322 --- /dev/null +++ b/src/test/ui/issues/issue-49955-2.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-49955.rs b/src/test/ui/issues/issue-49955.rs new file mode 100644 index 00000000000..f2f3ebff2db --- /dev/null +++ b/src/test/ui/issues/issue-49955.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-49973.rs b/src/test/ui/issues/issue-49973.rs new file mode 100644 index 00000000000..af421c52fb0 --- /dev/null +++ b/src/test/ui/issues/issue-49973.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs b/src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs new file mode 100644 index 00000000000..fc869ae4fec --- /dev/null +++ b/src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/issues/issue-50415.rs b/src/test/ui/issues/issue-50415.rs new file mode 100644 index 00000000000..20c7be772f9 --- /dev/null +++ b/src/test/ui/issues/issue-50415.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-50442.rs b/src/test/ui/issues/issue-50442.rs new file mode 100644 index 00000000000..25c7dde7a5f --- /dev/null +++ b/src/test/ui/issues/issue-50442.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-5060.rs b/src/test/ui/issues/issue-5060.rs new file mode 100644 index 00000000000..c4760bc029b --- /dev/null +++ b/src/test/ui/issues/issue-5060.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-50689.rs b/src/test/ui/issues/issue-50689.rs new file mode 100644 index 00000000000..b49f2950020 --- /dev/null +++ b/src/test/ui/issues/issue-50689.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +enum Foo { + Bar = (|x: i32| { }, 42).1, +} + +fn main() { + assert_eq!(Foo::Bar as usize, 42); +} diff --git a/src/test/ui/issues/issue-50731.rs b/src/test/ui/issues/issue-50731.rs new file mode 100644 index 00000000000..209c1e1279b --- /dev/null +++ b/src/test/ui/issues/issue-50731.rs @@ -0,0 +1,6 @@ +// run-pass +enum Void {} +fn foo(_: Result<(Void, u32), (Void, String)>) {} +fn main() { + let _: fn(_) = foo; +} diff --git a/src/test/ui/issues/issue-50811.rs b/src/test/ui/issues/issue-50811.rs new file mode 100644 index 00000000000..63d87e03c48 --- /dev/null +++ b/src/test/ui/issues/issue-50811.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs b/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs new file mode 100644 index 00000000000..f3a51b415fa --- /dev/null +++ b/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs @@ -0,0 +1,14 @@ +#![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/src/test/ui/issues/issue-50865-private-impl-trait/main.rs b/src/test/ui/issues/issue-50865-private-impl-trait/main.rs new file mode 100644 index 00000000000..16dfac53ad1 --- /dev/null +++ b/src/test/ui/issues/issue-50865-private-impl-trait/main.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-51185.rs b/src/test/ui/issues/issue-51185.rs new file mode 100644 index 00000000000..52a2b25539d --- /dev/null +++ b/src/test/ui/issues/issue-51185.rs @@ -0,0 +1,8 @@ +// run-pass +fn foo() -> impl Into fn(&'a ())> { + (|_| {}) as for<'a> fn(&'a ()) +} + +fn main() { + foo().into()(&()); +} diff --git a/src/test/ui/issues/issue-51345.rs b/src/test/ui/issues/issue-51345.rs new file mode 100644 index 00000000000..15571e8bf5b --- /dev/null +++ b/src/test/ui/issues/issue-51345.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unreachable_code)] + +fn main() { + let mut v = Vec::new(); + + loop { v.push(break) } +} diff --git a/src/test/ui/issues/issue-51582.rs b/src/test/ui/issues/issue-51582.rs new file mode 100644 index 00000000000..63ef05729bc --- /dev/null +++ b/src/test/ui/issues/issue-51582.rs @@ -0,0 +1,18 @@ +// 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, unsafe { std::intrinsics::discriminant_value(&make_b()) }); +} diff --git a/src/test/ui/issues/issue-51907.rs b/src/test/ui/issues/issue-51907.rs new file mode 100644 index 00000000000..3691fe19117 --- /dev/null +++ b/src/test/ui/issues/issue-51907.rs @@ -0,0 +1,17 @@ +// run-pass +trait Foo { + extern fn borrow(&self); + extern fn take(self: Box); +} + +struct Bar; +impl Foo for Bar { + extern fn borrow(&self) {} + extern fn take(self: Box) {} +} + +fn main() { + let foo: Box = Box::new(Bar); + foo.borrow(); + foo.take() +} diff --git a/src/test/ui/issues/issue-5192.rs b/src/test/ui/issues/issue-5192.rs new file mode 100644 index 00000000000..5a83d1c2ff9 --- /dev/null +++ b/src/test/ui/issues/issue-5192.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/issues/issue-52140/auxiliary/some_crate.rs b/src/test/ui/issues/issue-52140/auxiliary/some_crate.rs new file mode 100644 index 00000000000..087005849d1 --- /dev/null +++ b/src/test/ui/issues/issue-52140/auxiliary/some_crate.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] + +pub fn hello() { + println!("Hello, world!"); +} diff --git a/src/test/ui/issues/issue-52140/main.rs b/src/test/ui/issues/issue-52140/main.rs new file mode 100644 index 00000000000..aeac4340455 --- /dev/null +++ b/src/test/ui/issues/issue-52140/main.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-52141/auxiliary/some_crate.rs b/src/test/ui/issues/issue-52141/auxiliary/some_crate.rs new file mode 100644 index 00000000000..087005849d1 --- /dev/null +++ b/src/test/ui/issues/issue-52141/auxiliary/some_crate.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] + +pub fn hello() { + println!("Hello, world!"); +} diff --git a/src/test/ui/issues/issue-52141/main.rs b/src/test/ui/issues/issue-52141/main.rs new file mode 100644 index 00000000000..7eea1726cf3 --- /dev/null +++ b/src/test/ui/issues/issue-52141/main.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-52169.rs b/src/test/ui/issues/issue-52169.rs new file mode 100644 index 00000000000..60be97f0aee --- /dev/null +++ b/src/test/ui/issues/issue-52169.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-5239-2.rs b/src/test/ui/issues/issue-5239-2.rs new file mode 100644 index 00000000000..b501c6e1853 --- /dev/null +++ b/src/test/ui/issues/issue-5239-2.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-5243.rs b/src/test/ui/issues/issue-5243.rs new file mode 100644 index 00000000000..c511d45f02d --- /dev/null +++ b/src/test/ui/issues/issue-5243.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-52557.rs b/src/test/ui/issues/issue-52557.rs new file mode 100644 index 00000000000..09f7a8c5131 --- /dev/null +++ b/src/test/ui/issues/issue-52557.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-52705/auxiliary/png2.rs b/src/test/ui/issues/issue-52705/auxiliary/png2.rs new file mode 100644 index 00000000000..fa9956e440d --- /dev/null +++ b/src/test/ui/issues/issue-52705/auxiliary/png2.rs @@ -0,0 +1,3 @@ +#![crate_type = "lib"] + +pub struct DecodingError; diff --git a/src/test/ui/issues/issue-52705/main.rs b/src/test/ui/issues/issue-52705/main.rs new file mode 100644 index 00000000000..90bb8ca7537 --- /dev/null +++ b/src/test/ui/issues/issue-52705/main.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-5280.rs b/src/test/ui/issues/issue-5280.rs new file mode 100644 index 00000000000..3c97dad6b14 --- /dev/null +++ b/src/test/ui/issues/issue-5280.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-5315.rs b/src/test/ui/issues/issue-5315.rs new file mode 100644 index 00000000000..38c98254b93 --- /dev/null +++ b/src/test/ui/issues/issue-5315.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct A(bool); + +pub fn main() { + let f = A; + f(true); +} diff --git a/src/test/ui/issues/issue-5321-immediates-with-bare-self.rs b/src/test/ui/issues/issue-5321-immediates-with-bare-self.rs new file mode 100644 index 00000000000..64aa2836a7d --- /dev/null +++ b/src/test/ui/issues/issue-5321-immediates-with-bare-self.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-53333.rs b/src/test/ui/issues/issue-53333.rs new file mode 100644 index 00000000000..ccc9971f93c --- /dev/null +++ b/src/test/ui/issues/issue-53333.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_imports)] +// edition:2018 + +fn main() { + use std; + let std = "std"; + println!("{}", std); +} diff --git a/src/test/ui/issues/issue-53728.rs b/src/test/ui/issues/issue-53728.rs new file mode 100644 index 00000000000..77b5010f776 --- /dev/null +++ b/src/test/ui/issues/issue-53728.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/issues/issue-53843.rs b/src/test/ui/issues/issue-53843.rs new file mode 100644 index 00000000000..f305b370ce6 --- /dev/null +++ b/src/test/ui/issues/issue-53843.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs b/src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs new file mode 100644 index 00000000000..412028bdcdc --- /dev/null +++ b/src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/issues/issue-54467.rs b/src/test/ui/issues/issue-54467.rs new file mode 100644 index 00000000000..734bf2768c2 --- /dev/null +++ b/src/test/ui/issues/issue-54467.rs @@ -0,0 +1,46 @@ +// run-pass + +pub trait Stream { + type Item; + type Error; +} + +pub trait ParseError { + type Output; +} + +impl ParseError for u32 { + type Output = (); +} + +impl Stream for () { + type Item = char; + type Error = u32; +} + +pub struct Lex<'a, I> + where I: Stream, + I::Error: ParseError, + <::Error as ParseError>::Output: 'a +{ + x: &'a >::Output +} + +pub struct Reserved<'a, I> where + I: Stream + 'a, + I::Error: ParseError, + <::Error as ParseError>::Output: 'a + +{ + x: Lex<'a, I> +} + +fn main() { + let r: Reserved<()> = Reserved { + x: Lex { + x: &() + } + }; + + let _v = r.x.x; +} diff --git a/src/test/ui/issues/issue-54477-reduced-2.rs b/src/test/ui/issues/issue-54477-reduced-2.rs new file mode 100644 index 00000000000..199d69b4540 --- /dev/null +++ b/src/test/ui/issues/issue-54477-reduced-2.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-54696.rs b/src/test/ui/issues/issue-54696.rs new file mode 100644 index 00000000000..d8408ed8549 --- /dev/null +++ b/src/test/ui/issues/issue-54696.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/issues/issue-5518.rs b/src/test/ui/issues/issue-5518.rs new file mode 100644 index 00000000000..97ed9ef309d --- /dev/null +++ b/src/test/ui/issues/issue-5518.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-5518.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_5518 as other; + +fn main() {} diff --git a/src/test/ui/issues/issue-5521.rs b/src/test/ui/issues/issue-5521.rs new file mode 100644 index 00000000000..cafdbc39961 --- /dev/null +++ b/src/test/ui/issues/issue-5521.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-5530.rs b/src/test/ui/issues/issue-5530.rs new file mode 100644 index 00000000000..72731cbb177 --- /dev/null +++ b/src/test/ui/issues/issue-5530.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/issues/issue-55376.rs b/src/test/ui/issues/issue-55376.rs new file mode 100644 index 00000000000..4adff2b4544 --- /dev/null +++ b/src/test/ui/issues/issue-55376.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-55380.rs b/src/test/ui/issues/issue-55380.rs new file mode 100644 index 00000000000..862218e2192 --- /dev/null +++ b/src/test/ui/issues/issue-55380.rs @@ -0,0 +1,28 @@ +// run-pass + +#![feature(specialization)] + +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/src/test/ui/issues/issue-5550.rs b/src/test/ui/issues/issue-5550.rs new file mode 100644 index 00000000000..6ea24747b39 --- /dev/null +++ b/src/test/ui/issues/issue-5550.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-5554.rs b/src/test/ui/issues/issue-5554.rs new file mode 100644 index 00000000000..7737536f43d --- /dev/null +++ b/src/test/ui/issues/issue-5554.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-56237.rs b/src/test/ui/issues/issue-56237.rs new file mode 100644 index 00000000000..534b85acec8 --- /dev/null +++ b/src/test/ui/issues/issue-56237.rs @@ -0,0 +1,13 @@ +// run-pass + +use std::ops::Deref; + +fn foo

(_value:

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

::Target: Sized, +{} + +fn main() { + foo::>(2); +} diff --git a/src/test/ui/issues/issue-5666.rs b/src/test/ui/issues/issue-5666.rs new file mode 100644 index 00000000000..aa513277830 --- /dev/null +++ b/src/test/ui/issues/issue-5666.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-5688.rs b/src/test/ui/issues/issue-5688.rs new file mode 100644 index 00000000000..b6e364c2f40 --- /dev/null +++ b/src/test/ui/issues/issue-5688.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-5708.rs b/src/test/ui/issues/issue-5708.rs new file mode 100644 index 00000000000..6fe9943d368 --- /dev/null +++ b/src/test/ui/issues/issue-5708.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/issues/issue-5718.rs b/src/test/ui/issues/issue-5718.rs new file mode 100644 index 00000000000..63efec95311 --- /dev/null +++ b/src/test/ui/issues/issue-5718.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/issues/issue-5741.rs b/src/test/ui/issues/issue-5741.rs new file mode 100644 index 00000000000..b9eaf0be7fb --- /dev/null +++ b/src/test/ui/issues/issue-5741.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(while_true)] +#![allow(unreachable_code)] + +pub fn main() { + return; + while true {}; +} diff --git a/src/test/ui/issues/issue-5791.rs b/src/test/ui/issues/issue-5791.rs new file mode 100644 index 00000000000..2f8bf1e9369 --- /dev/null +++ b/src/test/ui/issues/issue-5791.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern { + #[link_name = "malloc"] + fn malloc1(len: i32) -> *const u8; + #[link_name = "malloc"] + fn malloc2(len: i32, foo: i32) -> *const u8; +} + +pub fn main () {} diff --git a/src/test/ui/issues/issue-58212.rs b/src/test/ui/issues/issue-58212.rs new file mode 100644 index 00000000000..21dcdd56bf6 --- /dev/null +++ b/src/test/ui/issues/issue-58212.rs @@ -0,0 +1,16 @@ +// run-pass + +trait FromUnchecked { + unsafe fn from_unchecked(); +} + +impl FromUnchecked for [u8; 1] { + unsafe fn from_unchecked() { + #[allow(deprecated)] + let mut array: Self = std::mem::uninitialized(); + let _ptr = &mut array as *mut [u8] as *mut u8; + } +} + +fn main() { +} diff --git a/src/test/ui/issues/issue-58435-ice-with-assoc-const.rs b/src/test/ui/issues/issue-58435-ice-with-assoc-const.rs new file mode 100644 index 00000000000..fac727d2d7d --- /dev/null +++ b/src/test/ui/issues/issue-58435-ice-with-assoc-const.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-58463.rs b/src/test/ui/issues/issue-58463.rs new file mode 100644 index 00000000000..8ab845366b7 --- /dev/null +++ b/src/test/ui/issues/issue-58463.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags:-C debuginfo=2 +fn foo() -> impl Copy { + foo +} +fn main() { + foo(); +} diff --git a/src/test/ui/issues/issue-5917.rs b/src/test/ui/issues/issue-5917.rs new file mode 100644 index 00000000000..6ab7081cf88 --- /dev/null +++ b/src/test/ui/issues/issue-5917.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/issues/issue-5988.rs b/src/test/ui/issues/issue-5988.rs new file mode 100644 index 00000000000..303fb4fbc94 --- /dev/null +++ b/src/test/ui/issues/issue-5988.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-5997.rs b/src/test/ui/issues/issue-5997.rs new file mode 100644 index 00000000000..145e3a7928d --- /dev/null +++ b/src/test/ui/issues/issue-5997.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-6117.rs b/src/test/ui/issues/issue-6117.rs new file mode 100644 index 00000000000..5235d53d84a --- /dev/null +++ b/src/test/ui/issues/issue-6117.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-6128.rs b/src/test/ui/issues/issue-6128.rs new file mode 100644 index 00000000000..8859fbe6afb --- /dev/null +++ b/src/test/ui/issues/issue-6128.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-6130.rs b/src/test/ui/issues/issue-6130.rs new file mode 100644 index 00000000000..a33ea686947 --- /dev/null +++ b/src/test/ui/issues/issue-6130.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-6153.rs b/src/test/ui/issues/issue-6153.rs new file mode 100644 index 00000000000..25f026f214b --- /dev/null +++ b/src/test/ui/issues/issue-6153.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/issues/issue-6157.rs b/src/test/ui/issues/issue-6157.rs new file mode 100644 index 00000000000..b7a44ed8623 --- /dev/null +++ b/src/test/ui/issues/issue-6157.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/issues/issue-61696.rs b/src/test/ui/issues/issue-61696.rs new file mode 100644 index 00000000000..dca52927fd7 --- /dev/null +++ b/src/test/ui/issues/issue-61696.rs @@ -0,0 +1,66 @@ +// 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/src/test/ui/issues/issue-61894.rs b/src/test/ui/issues/issue-61894.rs new file mode 100644 index 00000000000..c018ac73fb5 --- /dev/null +++ b/src/test/ui/issues/issue-61894.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-6318.rs b/src/test/ui/issues/issue-6318.rs new file mode 100644 index 00000000000..d8bd83f0dc6 --- /dev/null +++ b/src/test/ui/issues/issue-6318.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-6334.rs b/src/test/ui/issues/issue-6334.rs new file mode 100644 index 00000000000..acf48da1543 --- /dev/null +++ b/src/test/ui/issues/issue-6334.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/issues/issue-6344-let.rs b/src/test/ui/issues/issue-6344-let.rs new file mode 100644 index 00000000000..a7b6a2e2d66 --- /dev/null +++ b/src/test/ui/issues/issue-6344-let.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-6344-match.rs b/src/test/ui/issues/issue-6344-match.rs new file mode 100644 index 00000000000..4505a34c716 --- /dev/null +++ b/src/test/ui/issues/issue-6344-match.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-6449.rs b/src/test/ui/issues/issue-6449.rs new file mode 100644 index 00000000000..bfd4c123208 --- /dev/null +++ b/src/test/ui/issues/issue-6449.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/issues/issue-6892.rs b/src/test/ui/issues/issue-6892.rs new file mode 100644 index 00000000000..a361461a4ce --- /dev/null +++ b/src/test/ui/issues/issue-6892.rs @@ -0,0 +1,58 @@ +// 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/src/test/ui/issues/issue-6919.rs b/src/test/ui/issues/issue-6919.rs new file mode 100644 index 00000000000..11aed120873 --- /dev/null +++ b/src/test/ui/issues/issue-6919.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_attributes)] +// aux-build:iss.rs + +// pretty-expanded FIXME #23616 + +#![crate_id="issue-6919"] +extern crate issue6919_3; + +pub fn main() { + let _ = issue6919_3::D.k; +} diff --git a/src/test/ui/issues/issue-7012.rs b/src/test/ui/issues/issue-7012.rs new file mode 100644 index 00000000000..90eba170695 --- /dev/null +++ b/src/test/ui/issues/issue-7012.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-7178.rs b/src/test/ui/issues/issue-7178.rs new file mode 100644 index 00000000000..30aa736cdc6 --- /dev/null +++ b/src/test/ui/issues/issue-7178.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/issues/issue-7222.rs b/src/test/ui/issues/issue-7222.rs new file mode 100644 index 00000000000..64907316626 --- /dev/null +++ b/src/test/ui/issues/issue-7222.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-7344.rs b/src/test/ui/issues/issue-7344.rs new file mode 100644 index 00000000000..f1727d0c1ae --- /dev/null +++ b/src/test/ui/issues/issue-7344.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/issues/issue-7519-match-unit-in-arg.rs b/src/test/ui/issues/issue-7519-match-unit-in-arg.rs new file mode 100644 index 00000000000..7d838cbb09b --- /dev/null +++ b/src/test/ui/issues/issue-7519-match-unit-in-arg.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* +#7519 ICE pattern matching unit in function argument +*/ + +fn foo(():()) { } + +pub fn main() { + foo(()); +} diff --git a/src/test/ui/issues/issue-7563.rs b/src/test/ui/issues/issue-7563.rs new file mode 100644 index 00000000000..c62405554b4 --- /dev/null +++ b/src/test/ui/issues/issue-7563.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/issues/issue-7575.rs b/src/test/ui/issues/issue-7575.rs new file mode 100644 index 00000000000..ac69f2b1c80 --- /dev/null +++ b/src/test/ui/issues/issue-7575.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/issues/issue-7660.rs b/src/test/ui/issues/issue-7660.rs new file mode 100644 index 00000000000..ad0b8ecff39 --- /dev/null +++ b/src/test/ui/issues/issue-7660.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-7663.rs b/src/test/ui/issues/issue-7663.rs new file mode 100644 index 00000000000..b15e215db0f --- /dev/null +++ b/src/test/ui/issues/issue-7663.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs new file mode 100644 index 00000000000..b75e547079e --- /dev/null +++ b/src/test/ui/issues/issue-7784.rs @@ -0,0 +1,31 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/issues/issue-7899.rs b/src/test/ui/issues/issue-7899.rs new file mode 100644 index 00000000000..fb631f83697 --- /dev/null +++ b/src/test/ui/issues/issue-7899.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-7911.rs b/src/test/ui/issues/issue-7911.rs new file mode 100644 index 00000000000..de833324bd2 --- /dev/null +++ b/src/test/ui/issues/issue-7911.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/issues/issue-8044.rs b/src/test/ui/issues/issue-8044.rs new file mode 100644 index 00000000000..858f98b654d --- /dev/null +++ b/src/test/ui/issues/issue-8044.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-8248.rs b/src/test/ui/issues/issue-8248.rs new file mode 100644 index 00000000000..31a305c31be --- /dev/null +++ b/src/test/ui/issues/issue-8248.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/issues/issue-8249.rs b/src/test/ui/issues/issue-8249.rs new file mode 100644 index 00000000000..d09dff3a697 --- /dev/null +++ b/src/test/ui/issues/issue-8249.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/issues/issue-8259.rs b/src/test/ui/issues/issue-8259.rs new file mode 100644 index 00000000000..2802bea7fe0 --- /dev/null +++ b/src/test/ui/issues/issue-8259.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-8351-1.rs b/src/test/ui/issues/issue-8351-1.rs new file mode 100644 index 00000000000..139f027cb90 --- /dev/null +++ b/src/test/ui/issues/issue-8351-1.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-8351-2.rs b/src/test/ui/issues/issue-8351-2.rs new file mode 100644 index 00000000000..bc66cbb77c0 --- /dev/null +++ b/src/test/ui/issues/issue-8351-2.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-8391.rs b/src/test/ui/issues/issue-8391.rs new file mode 100644 index 00000000000..1a90369659b --- /dev/null +++ b/src/test/ui/issues/issue-8391.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + let x = match Some(1) { + ref _y @ Some(_) => 1, + None => 2, + }; + assert_eq!(x, 1); +} diff --git a/src/test/ui/issues/issue-8401.rs b/src/test/ui/issues/issue-8401.rs new file mode 100644 index 00000000000..1257bab6c0c --- /dev/null +++ b/src/test/ui/issues/issue-8401.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-8401.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_8401; + +pub fn main() {} diff --git a/src/test/ui/issues/issue-8460.rs b/src/test/ui/issues/issue-8460.rs new file mode 100644 index 00000000000..b7fc564a9b5 --- /dev/null +++ b/src/test/ui/issues/issue-8460.rs @@ -0,0 +1,51 @@ +// 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() -> $t { 0 } + fn one() -> $t { 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_value() / -isize::one(), + i8::min_value() / -i8::one(), + i16::min_value() / -i16::one(), + i32::min_value() / -i32::one(), + i64::min_value() / -i64::one(), + 1isize / isize::zero(), + 1i8 / i8::zero(), + 1i16 / i16::zero(), + 1i32 / i32::zero(), + 1i64 / i64::zero(), + isize::min_value() % -isize::one(), + i8::min_value() % -i8::one(), + i16::min_value() % -i16::one(), + i32::min_value() % -i32::one(), + i64::min_value() % -i64::one(), + 1isize % isize::zero(), + 1i8 % i8::zero(), + 1i16 % i16::zero(), + 1i32 % i32::zero(), + 1i64 % i64::zero() + ]; +} diff --git a/src/test/ui/issues/issue-8498.rs b/src/test/ui/issues/issue-8498.rs new file mode 100644 index 00000000000..e6241b76109 --- /dev/null +++ b/src/test/ui/issues/issue-8498.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/issues/issue-8506.rs b/src/test/ui/issues/issue-8506.rs new file mode 100644 index 00000000000..cc32b89234f --- /dev/null +++ b/src/test/ui/issues/issue-8506.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-868.rs b/src/test/ui/issues/issue-868.rs new file mode 100644 index 00000000000..ce0a3c7ca52 --- /dev/null +++ b/src/test/ui/issues/issue-868.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-8709.rs b/src/test/ui/issues/issue-8709.rs new file mode 100644 index 00000000000..ea7525d4477 --- /dev/null +++ b/src/test/ui/issues/issue-8709.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-8783.rs b/src/test/ui/issues/issue-8783.rs new file mode 100644 index 00000000000..4eb49c82161 --- /dev/null +++ b/src/test/ui/issues/issue-8783.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/issues/issue-8827.rs b/src/test/ui/issues/issue-8827.rs new file mode 100644 index 00000000000..95be7616a4f --- /dev/null +++ b/src/test/ui/issues/issue-8827.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/issues/issue-8851.rs b/src/test/ui/issues/issue-8851.rs new file mode 100644 index 00000000000..faacfe5f895 --- /dev/null +++ b/src/test/ui/issues/issue-8851.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-8860.rs b/src/test/ui/issues/issue-8860.rs new file mode 100644 index 00000000000..b89a80c1307 --- /dev/null +++ b/src/test/ui/issues/issue-8860.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/issues/issue-8898.rs b/src/test/ui/issues/issue-8898.rs new file mode 100644 index 00000000000..31d5ff86e7c --- /dev/null +++ b/src/test/ui/issues/issue-8898.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/issues/issue-9047.rs b/src/test/ui/issues/issue-9047.rs new file mode 100644 index 00000000000..fa8d75aec7a --- /dev/null +++ b/src/test/ui/issues/issue-9047.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/issues/issue-9123.rs b/src/test/ui/issues/issue-9123.rs new file mode 100644 index 00000000000..8c21d06c477 --- /dev/null +++ b/src/test/ui/issues/issue-9123.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-9123.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_9123; + +pub fn main() {} diff --git a/src/test/ui/issues/issue-9129.rs b/src/test/ui/issues/issue-9129.rs new file mode 100644 index 00000000000..3d87e1c2037 --- /dev/null +++ b/src/test/ui/issues/issue-9129.rs @@ -0,0 +1,35 @@ +// 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 { 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/src/test/ui/issues/issue-9155.rs b/src/test/ui/issues/issue-9155.rs new file mode 100644 index 00000000000..4b5c451e853 --- /dev/null +++ b/src/test/ui/issues/issue-9155.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/issues/issue-9188.rs b/src/test/ui/issues/issue-9188.rs new file mode 100644 index 00000000000..34e61fdf68b --- /dev/null +++ b/src/test/ui/issues/issue-9188.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-9259.rs b/src/test/ui/issues/issue-9259.rs new file mode 100644 index 00000000000..d838edbdd66 --- /dev/null +++ b/src/test/ui/issues/issue-9259.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/issues/issue-9382.rs b/src/test/ui/issues/issue-9382.rs new file mode 100644 index 00000000000..dbb0fa524ef --- /dev/null +++ b/src/test/ui/issues/issue-9382.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/issues/issue-9394-inherited-trait-calls.rs b/src/test/ui/issues/issue-9394-inherited-trait-calls.rs new file mode 100644 index 00000000000..cc0dd4fc14a --- /dev/null +++ b/src/test/ui/issues/issue-9394-inherited-trait-calls.rs @@ -0,0 +1,62 @@ +// 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/src/test/ui/issues/issue-9396.rs b/src/test/ui/issues/issue-9396.rs new file mode 100644 index 00000000000..27b5185377d --- /dev/null +++ b/src/test/ui/issues/issue-9396.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(deprecated)] +// ignore-emscripten no threads support +// ignore-sgx no thread sleep 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/src/test/ui/issues/issue-9446.rs b/src/test/ui/issues/issue-9446.rs new file mode 100644 index 00000000000..e200840d290 --- /dev/null +++ b/src/test/ui/issues/issue-9446.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/issues/issue-9737.rs b/src/test/ui/issues/issue-9737.rs new file mode 100644 index 00000000000..7d3e0567847 --- /dev/null +++ b/src/test/ui/issues/issue-9737.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_variables)] +macro_rules! f { + (v: $x:expr) => ( println!("{}", $x) ) +} + +fn main () { + let v = 5; + f!(v: 3); +} diff --git a/src/test/ui/issues/issue-979.rs b/src/test/ui/issues/issue-979.rs new file mode 100644 index 00000000000..57a99b325ad --- /dev/null +++ b/src/test/ui/issues/issue-979.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/issues/issue-9837.rs b/src/test/ui/issues/issue-9837.rs new file mode 100644 index 00000000000..5d2c822a576 --- /dev/null +++ b/src/test/ui/issues/issue-9837.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-9906.rs b/src/test/ui/issues/issue-9906.rs new file mode 100644 index 00000000000..a2870cf0f6e --- /dev/null +++ b/src/test/ui/issues/issue-9906.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/issues/issue-9918.rs b/src/test/ui/issues/issue-9918.rs new file mode 100644 index 00000000000..63ad7040d67 --- /dev/null +++ b/src/test/ui/issues/issue-9918.rs @@ -0,0 +1,5 @@ +// run-pass + +pub fn main() { + assert_eq!((0 + 0u8) as char, '\0'); +} diff --git a/src/test/ui/issues/issue-9942.rs b/src/test/ui/issues/issue-9942.rs new file mode 100644 index 00000000000..f4880446526 --- /dev/null +++ b/src/test/ui/issues/issue-9942.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + const S: usize = 23 as usize; [0; S]; () +} diff --git a/src/test/ui/issues/issue-9951.rs b/src/test/ui/issues/issue-9951.rs new file mode 100644 index 00000000000..2698a3b17c6 --- /dev/null +++ b/src/test/ui/issues/issue-9951.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/issues/issue-9968.rs b/src/test/ui/issues/issue-9968.rs new file mode 100644 index 00000000000..3ab90d99af9 --- /dev/null +++ b/src/test/ui/issues/issue-9968.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/istr.rs b/src/test/ui/istr.rs new file mode 100644 index 00000000000..dca6d40d59a --- /dev/null +++ b/src/test/ui/istr.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/item-name-overload.rs b/src/test/ui/item-name-overload.rs new file mode 100644 index 00000000000..c8a302a2c5b --- /dev/null +++ b/src/test/ui/item-name-overload.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/iterators/into-iterator-type-inference-shift.rs b/src/test/ui/iterators/into-iterator-type-inference-shift.rs new file mode 100644 index 00000000000..9151172fd15 --- /dev/null +++ b/src/test/ui/iterators/into-iterator-type-inference-shift.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/iterators/iter-cloned-type-inference.rs b/src/test/ui/iterators/iter-cloned-type-inference.rs new file mode 100644 index 00000000000..898e3371971 --- /dev/null +++ b/src/test/ui/iterators/iter-cloned-type-inference.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/iterators/iter-range.rs b/src/test/ui/iterators/iter-range.rs new file mode 100644 index 00000000000..993d93790e0 --- /dev/null +++ b/src/test/ui/iterators/iter-range.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs new file mode 100644 index 00000000000..5d67c7cbb42 --- /dev/null +++ b/src/test/ui/iterators/iter-step-overflow-debug.rs @@ -0,0 +1,21 @@ +// 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_value()..; + it.next().unwrap(); // 255 + it.next().unwrap(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + let mut it = i8::max_value()..; + it.next().unwrap(); // 127 + it.next().unwrap(); + }); + assert!(r.is_err()); +} diff --git a/src/test/ui/iterators/iter-step-overflow-ndebug.rs b/src/test/ui/iterators/iter-step-overflow-ndebug.rs new file mode 100644 index 00000000000..a0ad92071b6 --- /dev/null +++ b/src/test/ui/iterators/iter-step-overflow-ndebug.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags: -C debug_assertions=no + +fn main() { + let mut it = u8::max_value()..; + assert_eq!(it.next().unwrap(), 255); + assert_eq!(it.next().unwrap(), u8::min_value()); + + let mut it = i8::max_value()..; + assert_eq!(it.next().unwrap(), 127); + assert_eq!(it.next().unwrap(), i8::min_value()); +} diff --git a/src/test/ui/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs new file mode 100644 index 00000000000..ee4ab4d24c6 --- /dev/null +++ b/src/test/ui/iterators/iter-sum-overflow-debug.rs @@ -0,0 +1,27 @@ +// 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_value()].iter().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::max_value()].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::max_value()].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::max_value()].iter().cloned().product::(); + }); + assert!(r.is_err()); +} diff --git a/src/test/ui/iterators/iter-sum-overflow-ndebug.rs b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs new file mode 100644 index 00000000000..61d63d41fb8 --- /dev/null +++ b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -C debug_assertions=no + +fn main() { + assert_eq!([1i32, i32::max_value()].iter().sum::(), + 1i32.wrapping_add(i32::max_value())); + assert_eq!([2i32, i32::max_value()].iter().product::(), + 2i32.wrapping_mul(i32::max_value())); + + assert_eq!([1i32, i32::max_value()].iter().cloned().sum::(), + 1i32.wrapping_add(i32::max_value())); + assert_eq!([2i32, i32::max_value()].iter().cloned().product::(), + 2i32.wrapping_mul(i32::max_value())); +} diff --git a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs new file mode 100644 index 00000000000..429f8e0bc96 --- /dev/null +++ b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs @@ -0,0 +1,27 @@ +// 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_value()].iter().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::max_value()].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::max_value()].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::max_value()].iter().cloned().product::(); + }); + assert!(r.is_err()); +} diff --git a/src/test/ui/iterators/iter-zip.rs b/src/test/ui/iterators/iter-zip.rs new file mode 100644 index 00000000000..a76fa2408bb --- /dev/null +++ b/src/test/ui/iterators/iter-zip.rs @@ -0,0 +1,103 @@ +// run-pass +// Test that .zip() specialization preserves side effects +// in sideeffectful iterator adaptors. + +use std::cell::Cell; + +#[derive(Debug)] +struct CountClone(Cell); + +fn count_clone() -> CountClone { CountClone(Cell::new(0)) } + +impl PartialEq for CountClone { + fn eq(&self, rhs: &i32) -> bool { + self.0.get() == *rhs + } +} + +impl Clone for CountClone { + fn clone(&self) -> Self { + let ret = CountClone(self.0.clone()); + let n = self.0.get(); + self.0.set(n + 1); + ret + } +} + +fn test_zip_cloned_sideffectful() { + let xs = [count_clone(), count_clone(), count_clone(), count_clone()]; + let ys = [count_clone(), count_clone()]; + + for _ in xs.iter().cloned().zip(ys.iter().cloned()) { } + + assert_eq!(&xs, &[1, 1, 1, 0][..]); + assert_eq!(&ys, &[1, 1][..]); + + let xs = [count_clone(), count_clone()]; + let ys = [count_clone(), count_clone(), count_clone(), count_clone()]; + + for _ in xs.iter().cloned().zip(ys.iter().cloned()) { } + + assert_eq!(&xs, &[1, 1][..]); + assert_eq!(&ys, &[1, 1, 0, 0][..]); +} + +fn test_zip_map_sideffectful() { + let mut xs = [0; 6]; + let mut ys = [0; 4]; + + for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) { } + + assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]); + assert_eq!(&ys, &[1, 1, 1, 1]); + + let mut xs = [0; 4]; + let mut ys = [0; 6]; + + for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) { } + + assert_eq!(&xs, &[1, 1, 1, 1]); + assert_eq!(&ys, &[1, 1, 1, 1, 0, 0]); +} + +fn test_zip_map_rev_sideffectful() { + let mut xs = [0; 6]; + let mut ys = [0; 4]; + + { + let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)); + it.next_back(); + } + assert_eq!(&xs, &[0, 0, 0, 1, 1, 1]); + assert_eq!(&ys, &[0, 0, 0, 1]); + + let mut xs = [0; 6]; + let mut ys = [0; 4]; + + { + let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)); + (&mut it).take(5).count(); + it.next_back(); + } + assert_eq!(&xs, &[1, 1, 1, 1, 1, 1]); + assert_eq!(&ys, &[1, 1, 1, 1]); +} + +fn test_zip_nested_sideffectful() { + let mut xs = [0; 6]; + let ys = [0; 4]; + + { + // test that it has the side effect nested inside enumerate + let it = xs.iter_mut().map(|x| *x = 1).enumerate().zip(&ys); + it.count(); + } + assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]); +} + +fn main() { + test_zip_cloned_sideffectful(); + test_zip_map_sideffectful(); + test_zip_map_rev_sideffectful(); + test_zip_nested_sideffectful(); +} diff --git a/src/test/ui/keyword-changes-2012-07-31.rs b/src/test/ui/keyword-changes-2012-07-31.rs new file mode 100644 index 00000000000..1b38527ec29 --- /dev/null +++ b/src/test/ui/keyword-changes-2012-07-31.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/kindck-implicit-close-over-mut-var.rs b/src/test/ui/kindck-implicit-close-over-mut-var.rs new file mode 100644 index 00000000000..5b5d86eec2c --- /dev/null +++ b/src/test/ui/kindck-implicit-close-over-mut-var.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/kinds-in-metadata.rs b/src/test/ui/kinds-in-metadata.rs new file mode 100644 index 00000000000..136037a7acf --- /dev/null +++ b/src/test/ui/kinds-in-metadata.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/lambda-infer-unresolved.rs b/src/test/ui/lambda-infer-unresolved.rs new file mode 100644 index 00000000000..9cc466b28ec --- /dev/null +++ b/src/test/ui/lambda-infer-unresolved.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/lambda-var-hygiene.rs b/src/test/ui/lambda-var-hygiene.rs new file mode 100644 index 00000000000..bf06765e5dd --- /dev/null +++ b/src/test/ui/lambda-var-hygiene.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/large-records.rs b/src/test/ui/large-records.rs new file mode 100644 index 00000000000..7f850a94e89 --- /dev/null +++ b/src/test/ui/large-records.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/last-use-in-block.rs b/src/test/ui/last-use-in-block.rs new file mode 100644 index 00000000000..1ab847dcd8a --- /dev/null +++ b/src/test/ui/last-use-in-block.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/last-use-in-cap-clause.rs b/src/test/ui/last-use-in-cap-clause.rs new file mode 100644 index 00000000000..98d43463287 --- /dev/null +++ b/src/test/ui/last-use-in-cap-clause.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/last-use-is-capture.rs b/src/test/ui/last-use-is-capture.rs new file mode 100644 index 00000000000..af230877793 --- /dev/null +++ b/src/test/ui/last-use-is-capture.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/lazy-and-or.rs b/src/test/ui/lazy-and-or.rs new file mode 100644 index 00000000000..0b44a70a569 --- /dev/null +++ b/src/test/ui/lazy-and-or.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/lazy-init.rs b/src/test/ui/lazy-init.rs new file mode 100644 index 00000000000..a4b5d18bb33 --- /dev/null +++ b/src/test/ui/lazy-init.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/leak-unique-as-tydesc.rs b/src/test/ui/leak-unique-as-tydesc.rs new file mode 100644 index 00000000000..752081b78f2 --- /dev/null +++ b/src/test/ui/leak-unique-as-tydesc.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/lex-bare-cr-nondoc-comment.rs b/src/test/ui/lex-bare-cr-nondoc-comment.rs new file mode 100644 index 00000000000..5b528d6e1e1 --- /dev/null +++ b/src/test/ui/lex-bare-cr-nondoc-comment.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs new file mode 100644 index 00000000000..74292f5eb7e --- /dev/null +++ b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs @@ -0,0 +1,41 @@ +// run-pass +// ignore-tidy-cr ignore-license +// ignore-tidy-cr (repeated again because of tidy bug) +// license is ignored because tidy can't handle the CRLF here properly. + +// http://rust-lang.org/COPYRIGHT. +// + +// 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/src/test/ui/lexical-scoping.rs b/src/test/ui/lexical-scoping.rs new file mode 100644 index 00000000000..04904958a6c --- /dev/null +++ b/src/test/ui/lexical-scoping.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/lib-defaults.rs b/src/test/ui/lib-defaults.rs new file mode 100644 index 00000000000..cd0b0bb2321 --- /dev/null +++ b/src/test/ui/lib-defaults.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/link-cfg-works.rs b/src/test/ui/link-cfg-works.rs new file mode 100644 index 00000000000..fe1b569dff6 --- /dev/null +++ b/src/test/ui/link-cfg-works.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/link-section.rs b/src/test/ui/link-section.rs new file mode 100644 index 00000000000..6958eeda697 --- /dev/null +++ b/src/test/ui/link-section.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/linkage1.rs b/src/test/ui/linkage1.rs new file mode 100644 index 00000000000..bda4da53dbc --- /dev/null +++ b/src/test/ui/linkage1.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/lint-cap.rs b/src/test/ui/lint-cap.rs new file mode 100644 index 00000000000..461b923ccd4 --- /dev/null +++ b/src/test/ui/lint-cap.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags: --cap-lints allow + +#![deny(warnings)] + +use std::option; + +fn main() {} diff --git a/src/test/ui/lint-dead-code-associated-type.rs b/src/test/ui/lint-dead-code-associated-type.rs new file mode 100644 index 00000000000..1cf66e75a95 --- /dev/null +++ b/src/test/ui/lint-dead-code-associated-type.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/lint-dead-code-variant.rs b/src/test/ui/lint-dead-code-variant.rs new file mode 100644 index 00000000000..91c97232eed --- /dev/null +++ b/src/test/ui/lint-dead-code-variant.rs @@ -0,0 +1,14 @@ +// run-pass + +#![deny(dead_code)] + +enum Foo { + A, + B, +} + +pub fn main() { + match Foo::A { + Foo::A | Foo::B => Foo::B + }; +} diff --git a/src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs b/src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs new file mode 100644 index 00000000000..07a32904a5e --- /dev/null +++ b/src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/lint-unknown-lints-at-crate-level.rs b/src/test/ui/lint-unknown-lints-at-crate-level.rs new file mode 100644 index 00000000000..61d27f1eff1 --- /dev/null +++ b/src/test/ui/lint-unknown-lints-at-crate-level.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -D warnings -D unknown-lints + +#![allow(unknown_lints)] +#![allow(random_lint_name)] + +fn main() {} diff --git a/src/test/ui/list.rs b/src/test/ui/list.rs new file mode 100644 index 00000000000..2ac5733b419 --- /dev/null +++ b/src/test/ui/list.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/liveness-assign-imm-local-after-ret.rs b/src/test/ui/liveness-assign-imm-local-after-ret.rs new file mode 100644 index 00000000000..b463f4368d1 --- /dev/null +++ b/src/test/ui/liveness-assign-imm-local-after-ret.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/llvm-pr32379.rs b/src/test/ui/llvm-pr32379.rs new file mode 100644 index 00000000000..8a1f03241b1 --- /dev/null +++ b/src/test/ui/llvm-pr32379.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/log-err-phi.rs b/src/test/ui/log-err-phi.rs new file mode 100644 index 00000000000..c0e04d2c973 --- /dev/null +++ b/src/test/ui/log-err-phi.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + if false { + println!("{}", "foobar"); + } +} diff --git a/src/test/ui/log-knows-the-names-of-variants-in-std.rs b/src/test/ui/log-knows-the-names-of-variants-in-std.rs new file mode 100644 index 00000000000..c5a40edbeef --- /dev/null +++ b/src/test/ui/log-knows-the-names-of-variants-in-std.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/log-knows-the-names-of-variants.rs b/src/test/ui/log-knows-the-names-of-variants.rs new file mode 100644 index 00000000000..cf2876b6eee --- /dev/null +++ b/src/test/ui/log-knows-the-names-of-variants.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/log-poly.rs b/src/test/ui/log-poly.rs new file mode 100644 index 00000000000..14e1b40e168 --- /dev/null +++ b/src/test/ui/log-poly.rs @@ -0,0 +1,13 @@ +// run-pass + +#[derive(Debug)] +enum Numbers { + Three +} + +pub fn main() { + println!("{:?}", 1); + println!("{:?}", 2.0f64); + println!("{:?}", Numbers::Three); + println!("{:?}", vec![4]); +} diff --git a/src/test/ui/logging-only-prints-once.rs b/src/test/ui/logging-only-prints-once.rs new file mode 100644 index 00000000000..6b49c441d1e --- /dev/null +++ b/src/test/ui/logging-only-prints-once.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-windows +// ignore-emscripten no threads support +// exec-env:RUSTC_LOG=debug + +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/src/test/ui/logging_before_rt_started.rs b/src/test/ui/logging_before_rt_started.rs new file mode 100644 index 00000000000..540d2b4f58a --- /dev/null +++ b/src/test/ui/logging_before_rt_started.rs @@ -0,0 +1,12 @@ +// run-pass +// exec-env:RUSTC_LOG=std::ptr + +// In issue #9487, it was realized that std::ptr was invoking the logging +// infrastructure, and when std::ptr was used during runtime initialization, +// this caused some serious problems. The problems have since been fixed, but +// this test will trigger "output during runtime initialization" to make sure +// that the bug isn't re-introduced. + +// pretty-expanded FIXME #23616 + +pub fn main() {} diff --git a/src/test/ui/long-while.rs b/src/test/ui/long-while.rs new file mode 100644 index 00000000000..529cca7b731 --- /dev/null +++ b/src/test/ui/long-while.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/lto-many-codegen-units.rs b/src/test/ui/lto-many-codegen-units.rs new file mode 100644 index 00000000000..f0f461ffec8 --- /dev/null +++ b/src/test/ui/lto-many-codegen-units.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: -C lto -C codegen-units=8 +// no-prefer-dynamic + +fn main() { +} diff --git a/src/test/ui/lto-still-runs-thread-dtors.rs b/src/test/ui/lto-still-runs-thread-dtors.rs new file mode 100644 index 00000000000..635ad783b31 --- /dev/null +++ b/src/test/ui/lto-still-runs-thread-dtors.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/lub-glb-with-unbound-infer-var.rs b/src/test/ui/lub-glb-with-unbound-infer-var.rs new file mode 100644 index 00000000000..c9e117089f5 --- /dev/null +++ b/src/test/ui/lub-glb-with-unbound-infer-var.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/macro-quote-cond.rs b/src/test/ui/macro-quote-cond.rs new file mode 100644 index 00000000000..569451e4259 --- /dev/null +++ b/src/test/ui/macro-quote-cond.rs @@ -0,0 +1,48 @@ +// run-pass + +#![allow(unused_parens)] +// aux-build:cond_plugin.rs + +#![feature(proc_macro_hygiene)] + +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/src/test/ui/macro-quote-test.rs b/src/test/ui/macro-quote-test.rs new file mode 100644 index 00000000000..7815b8e6df1 --- /dev/null +++ b/src/test/ui/macro-quote-test.rs @@ -0,0 +1,12 @@ +// run-pass +// Test that a macro can emit delimiters with nothing inside - `()`, `{}` + +// aux-build:hello_macro.rs + +#![feature(proc_macro_hygiene)] + +extern crate hello_macro; + +fn main() { + hello_macro::hello!(); +} diff --git a/src/test/ui/macros/assert-eq-macro-success.rs b/src/test/ui/macros/assert-eq-macro-success.rs new file mode 100644 index 00000000000..57858b34837 --- /dev/null +++ b/src/test/ui/macros/assert-eq-macro-success.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/macros/assert-eq-macro-unsized.rs b/src/test/ui/macros/assert-eq-macro-unsized.rs new file mode 100644 index 00000000000..00823216bf6 --- /dev/null +++ b/src/test/ui/macros/assert-eq-macro-unsized.rs @@ -0,0 +1,4 @@ +// run-pass +pub fn main() { + assert_eq!([1, 2, 3][..], vec![1, 2, 3][..]); +} diff --git a/src/test/ui/macros/assert-ne-macro-success.rs b/src/test/ui/macros/assert-ne-macro-success.rs new file mode 100644 index 00000000000..89b3a4c9d6a --- /dev/null +++ b/src/test/ui/macros/assert-ne-macro-success.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/macros/assert-ne-macro-unsized.rs b/src/test/ui/macros/assert-ne-macro-unsized.rs new file mode 100644 index 00000000000..e8a86e3da06 --- /dev/null +++ b/src/test/ui/macros/assert-ne-macro-unsized.rs @@ -0,0 +1,4 @@ +// run-pass +pub fn main() { + assert_ne!([6, 6, 6][..], vec![1, 2, 3][..]); +} diff --git a/src/test/ui/macros/auxiliary/macro-comma-support.rs b/src/test/ui/macros/auxiliary/macro-comma-support.rs new file mode 100644 index 00000000000..6a452c185a8 --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro-comma-support.rs @@ -0,0 +1 @@ +() diff --git a/src/test/ui/macros/auxiliary/macro-include-items-expr.rs b/src/test/ui/macros/auxiliary/macro-include-items-expr.rs new file mode 100644 index 00000000000..7394f194b80 --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro-include-items-expr.rs @@ -0,0 +1,3 @@ +// ignore-test: this is not a test + +1 diff --git a/src/test/ui/macros/auxiliary/macro-include-items-item.rs b/src/test/ui/macros/auxiliary/macro-include-items-item.rs new file mode 100644 index 00000000000..7d54745e03b --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro-include-items-item.rs @@ -0,0 +1,3 @@ +// ignore-test: this is not a test + +fn foo() { bar() } diff --git a/src/test/ui/macros/auxiliary/macro_crate_def_only.rs b/src/test/ui/macros/auxiliary/macro_crate_def_only.rs new file mode 100644 index 00000000000..c267eefde02 --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro_crate_def_only.rs @@ -0,0 +1,4 @@ +#[macro_export] +macro_rules! make_a_5 { + () => (5) +} diff --git a/src/test/ui/macros/auxiliary/macro_export_inner_module.rs b/src/test/ui/macros/auxiliary/macro_export_inner_module.rs new file mode 100644 index 00000000000..d71af9ee6f2 --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro_export_inner_module.rs @@ -0,0 +1,6 @@ +pub mod inner { + #[macro_export] + macro_rules! foo { + () => (1) + } +} diff --git a/src/test/ui/macros/auxiliary/macro_with_super_1.rs b/src/test/ui/macros/auxiliary/macro_with_super_1.rs new file mode 100644 index 00000000000..b015500df06 --- /dev/null +++ b/src/test/ui/macros/auxiliary/macro_with_super_1.rs @@ -0,0 +1,16 @@ +#![crate_type = "lib"] + +#[macro_export] +macro_rules! declare { + () => ( + pub fn aaa() {} + + pub mod bbb { + use super::aaa; + + pub fn ccc() { + aaa(); + } + } + ) +} diff --git a/src/test/ui/macros/auxiliary/two_macros-rpass.rs b/src/test/ui/macros/auxiliary/two_macros-rpass.rs new file mode 100644 index 00000000000..441a978dd69 --- /dev/null +++ b/src/test/ui/macros/auxiliary/two_macros-rpass.rs @@ -0,0 +1,5 @@ +#[macro_export] +macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } + +#[macro_export] +macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } diff --git a/src/test/ui/macros/auxiliary/use-macro-self.rs b/src/test/ui/macros/auxiliary/use-macro-self.rs new file mode 100644 index 00000000000..f1307411a7f --- /dev/null +++ b/src/test/ui/macros/auxiliary/use-macro-self.rs @@ -0,0 +1,6 @@ +pub mod foobarius {} + +#[macro_export] +macro_rules! foobarius { + () => { () } +} diff --git a/src/test/ui/macros/colorful-write-macros.rs b/src/test/ui/macros/colorful-write-macros.rs new file mode 100644 index 00000000000..eb1872cc7f0 --- /dev/null +++ b/src/test/ui/macros/colorful-write-macros.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/macros/conditional-debug-macro-on.rs b/src/test/ui/macros/conditional-debug-macro-on.rs new file mode 100644 index 00000000000..8665da89758 --- /dev/null +++ b/src/test/ui/macros/conditional-debug-macro-on.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/macros/die-macro.rs b/src/test/ui/macros/die-macro.rs new file mode 100644 index 00000000000..2a726efe822 --- /dev/null +++ b/src/test/ui/macros/die-macro.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/macros/issue-25274.rs b/src/test/ui/macros/issue-25274.rs new file mode 100644 index 00000000000..65b29bba8c8 --- /dev/null +++ b/src/test/ui/macros/issue-25274.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs new file mode 100644 index 00000000000..2d78ae6f908 --- /dev/null +++ b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout new file mode 100644 index 00000000000..b28b04f6431 --- /dev/null +++ b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout @@ -0,0 +1,3 @@ + + + diff --git a/src/test/ui/macros/macro-2.rs b/src/test/ui/macros/macro-2.rs new file mode 100644 index 00000000000..4890c991dcd --- /dev/null +++ b/src/test/ui/macros/macro-2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/macros/macro-as-fn-body.rs b/src/test/ui/macros/macro-as-fn-body.rs new file mode 100644 index 00000000000..6781c9a9ed4 --- /dev/null +++ b/src/test/ui/macros/macro-as-fn-body.rs @@ -0,0 +1,33 @@ +// +// 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/src/test/ui/macros/macro-attribute-expansion.rs b/src/test/ui/macros/macro-attribute-expansion.rs new file mode 100644 index 00000000000..f01e5c44a67 --- /dev/null +++ b/src/test/ui/macros/macro-attribute-expansion.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/macros/macro-attributes.rs b/src/test/ui/macros/macro-attributes.rs new file mode 100644 index 00000000000..d382e8b7197 --- /dev/null +++ b/src/test/ui/macros/macro-attributes.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/macros/macro-block-nonterminal.rs b/src/test/ui/macros/macro-block-nonterminal.rs new file mode 100644 index 00000000000..a6c9dd6e187 --- /dev/null +++ b/src/test/ui/macros/macro-block-nonterminal.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/macros/macro-crate-def-only.rs b/src/test/ui/macros/macro-crate-def-only.rs new file mode 100644 index 00000000000..514b33e3897 --- /dev/null +++ b/src/test/ui/macros/macro-crate-def-only.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/macros/macro-crate-nonterminal-renamed.rs b/src/test/ui/macros/macro-crate-nonterminal-renamed.rs new file mode 100644 index 00000000000..87bd397f065 --- /dev/null +++ b/src/test/ui/macros/macro-crate-nonterminal-renamed.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/macros/macro-crate-nonterminal.rs b/src/test/ui/macros/macro-crate-nonterminal.rs new file mode 100644 index 00000000000..4b1056fc725 --- /dev/null +++ b/src/test/ui/macros/macro-crate-nonterminal.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/macros/macro-crate-use.rs b/src/test/ui/macros/macro-crate-use.rs new file mode 100644 index 00000000000..5c37cac9686 --- /dev/null +++ b/src/test/ui/macros/macro-crate-use.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/macros/macro-deep_expansion.rs b/src/test/ui/macros/macro-deep_expansion.rs new file mode 100644 index 00000000000..e13d8e1fc84 --- /dev/null +++ b/src/test/ui/macros/macro-deep_expansion.rs @@ -0,0 +1,17 @@ +// run-pass + +macro_rules! foo2 { + () => { + "foo" + } +} + +macro_rules! foo { + () => { + foo2!() + } +} + +fn main() { + assert_eq!(concat!(foo!(), "bar"), "foobar") +} diff --git a/src/test/ui/macros/macro-delimiter-significance.rs b/src/test/ui/macros/macro-delimiter-significance.rs new file mode 100644 index 00000000000..89f222b0530 --- /dev/null +++ b/src/test/ui/macros/macro-delimiter-significance.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + vec![1_usize, 2, 3].len(); +} diff --git a/src/test/ui/macros/macro-doc-comments.rs b/src/test/ui/macros/macro-doc-comments.rs new file mode 100644 index 00000000000..fcc64cc0670 --- /dev/null +++ b/src/test/ui/macros/macro-doc-comments.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/macros/macro-doc-escapes.rs b/src/test/ui/macros/macro-doc-escapes.rs new file mode 100644 index 00000000000..ff5a5793b20 --- /dev/null +++ b/src/test/ui/macros/macro-doc-escapes.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/macros/macro-doc-raw-str-hashes.rs b/src/test/ui/macros/macro-doc-raw-str-hashes.rs new file mode 100644 index 00000000000..a003bff3c04 --- /dev/null +++ b/src/test/ui/macros/macro-doc-raw-str-hashes.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/macros/macro-export-inner-module.rs b/src/test/ui/macros/macro-export-inner-module.rs new file mode 100644 index 00000000000..1f23e90b65c --- /dev/null +++ b/src/test/ui/macros/macro-export-inner-module.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/macros/macro-first-set.rs b/src/test/ui/macros/macro-first-set.rs new file mode 100644 index 00000000000..a21e4cd201a --- /dev/null +++ b/src/test/ui/macros/macro-first-set.rs @@ -0,0 +1,277 @@ +// 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_meta_block { + ($($m:meta)* $b:block) => {}; +} + +test_meta_block!(windows {}); + +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/src/test/ui/macros/macro-followed-by-seq.rs b/src/test/ui/macros/macro-followed-by-seq.rs new file mode 100644 index 00000000000..71d59d8d31b --- /dev/null +++ b/src/test/ui/macros/macro-followed-by-seq.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/macros/macro-include-items.rs b/src/test/ui/macros/macro-include-items.rs new file mode 100644 index 00000000000..332bf59c944 --- /dev/null +++ b/src/test/ui/macros/macro-include-items.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/macros/macro-interpolation.rs b/src/test/ui/macros/macro-interpolation.rs new file mode 100644 index 00000000000..abe1f2aaf15 --- /dev/null +++ b/src/test/ui/macros/macro-interpolation.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs new file mode 100644 index 00000000000..8f9dcb94794 --- /dev/null +++ b/src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +macro_rules! four { + () => (4) +} + +fn main() { + let _x: [u16; four!()]; +} diff --git a/src/test/ui/macros/macro-lifetime-used-with-bound.rs b/src/test/ui/macros/macro-lifetime-used-with-bound.rs new file mode 100644 index 00000000000..ea3f74c9ada --- /dev/null +++ b/src/test/ui/macros/macro-lifetime-used-with-bound.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/macros/macro-lifetime-used-with-labels.rs b/src/test/ui/macros/macro-lifetime-used-with-labels.rs new file mode 100644 index 00000000000..4c4bccbc12b --- /dev/null +++ b/src/test/ui/macros/macro-lifetime-used-with-labels.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(stable_features)] + +#![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 { + 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/src/test/ui/macros/macro-lifetime-used-with-labels.stderr b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr new file mode 100644 index 00000000000..05418d9bddf --- /dev/null +++ b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr @@ -0,0 +1,11 @@ +warning: label name `'b` shadows a label name that is already in scope + --> $DIR/macro-lifetime-used-with-labels.rs:21:9 + | +LL | 'b: loop { + | ^^ lifetime 'b already in scope +... +LL | 'b: loop { + | -- first declared here +LL | br2!('b); + | --------- in this macro invocation + diff --git a/src/test/ui/macros/macro-lifetime-used-with-static.rs b/src/test/ui/macros/macro-lifetime-used-with-static.rs new file mode 100644 index 00000000000..8552c4b8163 --- /dev/null +++ b/src/test/ui/macros/macro-lifetime-used-with-static.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/macros/macro-lifetime.rs b/src/test/ui/macros/macro-lifetime.rs new file mode 100644 index 00000000000..5931fe00907 --- /dev/null +++ b/src/test/ui/macros/macro-lifetime.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/macros/macro-literal.rs b/src/test/ui/macros/macro-literal.rs new file mode 100644 index 00000000000..e08d0a67b43 --- /dev/null +++ b/src/test/ui/macros/macro-literal.rs @@ -0,0 +1,133 @@ +// 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/src/test/ui/macros/macro-meta-items.rs b/src/test/ui/macros/macro-meta-items.rs new file mode 100644 index 00000000000..4cbc252aebf --- /dev/null +++ b/src/test/ui/macros/macro-meta-items.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/macros/macro-method-issue-4621.rs b/src/test/ui/macros/macro-method-issue-4621.rs new file mode 100644 index 00000000000..342fad5f62e --- /dev/null +++ b/src/test/ui/macros/macro-method-issue-4621.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/macros/macro-multiple-items.rs b/src/test/ui/macros/macro-multiple-items.rs new file mode 100644 index 00000000000..3b6dfd9bc5e --- /dev/null +++ b/src/test/ui/macros/macro-multiple-items.rs @@ -0,0 +1,16 @@ +// run-pass +macro_rules! make_foo { + () => ( + struct Foo; + + impl Foo { + fn bar(&self) {} + } + ) +} + +make_foo!(); + +pub fn main() { + Foo.bar() +} diff --git a/src/test/ui/macros/macro-named-default.rs b/src/test/ui/macros/macro-named-default.rs new file mode 100644 index 00000000000..9b6cd191640 --- /dev/null +++ b/src/test/ui/macros/macro-named-default.rs @@ -0,0 +1,18 @@ +// run-pass +macro_rules! default { + ($($x:tt)*) => { $($x)* } +} + +default! { + struct A; +} + +impl A { + default! { + fn foo(&self) {} + } +} + +fn main() { + A.foo(); +} diff --git a/src/test/ui/macros/macro-nested_definition_issue-31946.rs b/src/test/ui/macros/macro-nested_definition_issue-31946.rs new file mode 100644 index 00000000000..a83c5b2e44f --- /dev/null +++ b/src/test/ui/macros/macro-nested_definition_issue-31946.rs @@ -0,0 +1,9 @@ +// run-pass +fn main() { + println!("{}", { + macro_rules! foo { + ($name:expr) => { concat!("hello ", $name) } + } + foo!("rust") + }); +} diff --git a/src/test/ui/macros/macro-nested_expr.rs b/src/test/ui/macros/macro-nested_expr.rs new file mode 100644 index 00000000000..f1433cbf4f9 --- /dev/null +++ b/src/test/ui/macros/macro-nested_expr.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/macros/macro-nested_stmt_macros.rs b/src/test/ui/macros/macro-nested_stmt_macros.rs new file mode 100644 index 00000000000..5d4758a0c7b --- /dev/null +++ b/src/test/ui/macros/macro-nested_stmt_macros.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/macros/macro-nt-list.rs b/src/test/ui/macros/macro-nt-list.rs new file mode 100644 index 00000000000..36aa74f0825 --- /dev/null +++ b/src/test/ui/macros/macro-nt-list.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/macros/macro-of-higher-order.rs b/src/test/ui/macros/macro-of-higher-order.rs new file mode 100644 index 00000000000..ec551d6cdbc --- /dev/null +++ b/src/test/ui/macros/macro-of-higher-order.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/macros/macro-pat-follow.rs b/src/test/ui/macros/macro-pat-follow.rs new file mode 100644 index 00000000000..8673cf79467 --- /dev/null +++ b/src/test/ui/macros/macro-pat-follow.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/macros/macro-pat-neg-lit.rs b/src/test/ui/macros/macro-pat-neg-lit.rs new file mode 100644 index 00000000000..79c68fd2541 --- /dev/null +++ b/src/test/ui/macros/macro-pat-neg-lit.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/macros/macro-pat.rs b/src/test/ui/macros/macro-pat.rs new file mode 100644 index 00000000000..baf816e53ea --- /dev/null +++ b/src/test/ui/macros/macro-pat.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/macros/macro-path.rs b/src/test/ui/macros/macro-path.rs new file mode 100644 index 00000000000..be59d8d139b --- /dev/null +++ b/src/test/ui/macros/macro-path.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/macros/macro-pub-matcher.rs b/src/test/ui/macros/macro-pub-matcher.rs new file mode 100644 index 00000000000..c02e6794edb --- /dev/null +++ b/src/test/ui/macros/macro-pub-matcher.rs @@ -0,0 +1,118 @@ +// 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/src/test/ui/macros/macro-seq-followed-by-seq.rs b/src/test/ui/macros/macro-seq-followed-by-seq.rs new file mode 100644 index 00000000000..8f0f4fd4a0d --- /dev/null +++ b/src/test/ui/macros/macro-seq-followed-by-seq.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/macros/macro-stmt.rs b/src/test/ui/macros/macro-stmt.rs new file mode 100644 index 00000000000..c9a0b879a0f --- /dev/null +++ b/src/test/ui/macros/macro-stmt.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs b/src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs new file mode 100644 index 00000000000..528d0b28bf6 --- /dev/null +++ b/src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/macros/macro-tt-followed-by-seq.rs b/src/test/ui/macros/macro-tt-followed-by-seq.rs new file mode 100644 index 00000000000..90131ebd920 --- /dev/null +++ b/src/test/ui/macros/macro-tt-followed-by-seq.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/macros/macro-use-all-and-none.rs b/src/test/ui/macros/macro-use-all-and-none.rs new file mode 100644 index 00000000000..e5f67d458d2 --- /dev/null +++ b/src/test/ui/macros/macro-use-all-and-none.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:two_macros-rpass.rs + +#![warn(unused_attributes)] + +#[macro_use] +#[macro_use()] +extern crate two_macros_rpass; + +pub fn main() { + macro_one!(); + macro_two!(); +} diff --git a/src/test/ui/macros/macro-use-all-and-none.stderr b/src/test/ui/macros/macro-use-all-and-none.stderr new file mode 100644 index 00000000000..e7de7e7ad08 --- /dev/null +++ b/src/test/ui/macros/macro-use-all-and-none.stderr @@ -0,0 +1,12 @@ +warning: unused attribute + --> $DIR/macro-use-all-and-none.rs:7:1 + | +LL | #[macro_use()] + | ^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/macro-use-all-and-none.rs:4:9 + | +LL | #![warn(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/macros/macro-use-all.rs b/src/test/ui/macros/macro-use-all.rs new file mode 100644 index 00000000000..48c7b77e579 --- /dev/null +++ b/src/test/ui/macros/macro-use-all.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use] +extern crate two_macros; + +pub fn main() { + macro_one!(); + macro_two!(); +} diff --git a/src/test/ui/macros/macro-use-both.rs b/src/test/ui/macros/macro-use-both.rs new file mode 100644 index 00000000000..ed5d1312f96 --- /dev/null +++ b/src/test/ui/macros/macro-use-both.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/macros/macro-use-one.rs b/src/test/ui/macros/macro-use-one.rs new file mode 100644 index 00000000000..f74795e68dc --- /dev/null +++ b/src/test/ui/macros/macro-use-one.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use(macro_two)] +extern crate two_macros; + +pub fn main() { + macro_two!(); +} diff --git a/src/test/ui/macros/macro-with-attrs1.rs b/src/test/ui/macros/macro-with-attrs1.rs new file mode 100644 index 00000000000..4e943b224cd --- /dev/null +++ b/src/test/ui/macros/macro-with-attrs1.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/macros/macro-with-attrs2.rs b/src/test/ui/macros/macro-with-attrs2.rs new file mode 100644 index 00000000000..78c40810207 --- /dev/null +++ b/src/test/ui/macros/macro-with-attrs2.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/macros/macro-with-braces-in-expr-position.rs b/src/test/ui/macros/macro-with-braces-in-expr-position.rs new file mode 100644 index 00000000000..f7d87434ded --- /dev/null +++ b/src/test/ui/macros/macro-with-braces-in-expr-position.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/macros/macro_with_super_2.rs b/src/test/ui/macros/macro_with_super_2.rs new file mode 100644 index 00000000000..2901a74f612 --- /dev/null +++ b/src/test/ui/macros/macro_with_super_2.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/macros/meta-variable-misuse.rs b/src/test/ui/macros/meta-variable-misuse.rs new file mode 100644 index 00000000000..99a2f940176 --- /dev/null +++ b/src/test/ui/macros/meta-variable-misuse.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/macros/parse-complex-macro-invoc-op.rs b/src/test/ui/macros/parse-complex-macro-invoc-op.rs new file mode 100644 index 00000000000..8fef9b0ed87 --- /dev/null +++ b/src/test/ui/macros/parse-complex-macro-invoc-op.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/macros/paths-in-macro-invocations.rs b/src/test/ui/macros/paths-in-macro-invocations.rs new file mode 100644 index 00000000000..622818a926f --- /dev/null +++ b/src/test/ui/macros/paths-in-macro-invocations.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/macros/pub-item-inside-macro.rs b/src/test/ui/macros/pub-item-inside-macro.rs new file mode 100644 index 00000000000..d07681453a2 --- /dev/null +++ b/src/test/ui/macros/pub-item-inside-macro.rs @@ -0,0 +1,18 @@ +// run-pass +// Issue #14660 + +// pretty-expanded FIXME #23616 + +mod bleh { + macro_rules! foo { + () => { + pub fn bar() { } + } + } + + foo!(); +} + +fn main() { + bleh::bar(); +} diff --git a/src/test/ui/macros/pub-method-inside-macro.rs b/src/test/ui/macros/pub-method-inside-macro.rs new file mode 100644 index 00000000000..bc918c7a4dc --- /dev/null +++ b/src/test/ui/macros/pub-method-inside-macro.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/macros/semi-after-macro-ty.rs b/src/test/ui/macros/semi-after-macro-ty.rs new file mode 100644 index 00000000000..f83ace8fada --- /dev/null +++ b/src/test/ui/macros/semi-after-macro-ty.rs @@ -0,0 +1,8 @@ +// run-pass +macro_rules! foo { + ($t:ty; $p:path;) => {} +} + +fn main() { + foo!(i32; i32;); +} diff --git a/src/test/ui/macros/stmt_expr_attr_macro_parse.rs b/src/test/ui/macros/stmt_expr_attr_macro_parse.rs new file mode 100644 index 00000000000..3ab50db0ea1 --- /dev/null +++ b/src/test/ui/macros/stmt_expr_attr_macro_parse.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/macros/syntax-extension-cfg.rs b/src/test/ui/macros/syntax-extension-cfg.rs new file mode 100644 index 00000000000..2e929fc1dfa --- /dev/null +++ b/src/test/ui/macros/syntax-extension-cfg.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment b/src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment new file mode 100644 index 00000000000..d752015a4dc --- /dev/null +++ b/src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment @@ -0,0 +1,7 @@ +/* this is for run-pass/syntax-extension-source-utils.rs */ + +{ + assert!(file!().ends_with("includeme.fragment")); + assert_eq!(line!(), 5u32); + format!("victory robot {}", line!()) +} diff --git a/src/test/ui/macros/syntax-extension-source-utils.rs b/src/test/ui/macros/syntax-extension-source-utils.rs new file mode 100644 index 00000000000..7e46260d516 --- /dev/null +++ b/src/test/ui/macros/syntax-extension-source-utils.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/macros/try-macro.rs b/src/test/ui/macros/try-macro.rs new file mode 100644 index 00000000000..83b30a8b7ba --- /dev/null +++ b/src/test/ui/macros/try-macro.rs @@ -0,0 +1,48 @@ +// run-pass +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/src/test/ui/macros/two-macro-use.rs b/src/test/ui/macros/two-macro-use.rs new file mode 100644 index 00000000000..07022bb01e3 --- /dev/null +++ b/src/test/ui/macros/two-macro-use.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/macros/type-macros-hlist.rs b/src/test/ui/macros/type-macros-hlist.rs new file mode 100644 index 00000000000..77d866cea9c --- /dev/null +++ b/src/test/ui/macros/type-macros-hlist.rs @@ -0,0 +1,78 @@ +// 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/src/test/ui/macros/type-macros-simple.rs b/src/test/ui/macros/type-macros-simple.rs new file mode 100644 index 00000000000..dd3ad2ef0ac --- /dev/null +++ b/src/test/ui/macros/type-macros-simple.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/macros/typeck-macro-interaction-issue-8852.rs b/src/test/ui/macros/typeck-macro-interaction-issue-8852.rs new file mode 100644 index 00000000000..f2b089b74b5 --- /dev/null +++ b/src/test/ui/macros/typeck-macro-interaction-issue-8852.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/macros/use-macro-self.rs b/src/test/ui/macros/use-macro-self.rs new file mode 100644 index 00000000000..06464ab0bc9 --- /dev/null +++ b/src/test/ui/macros/use-macro-self.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/max-min-classes.rs b/src/test/ui/max-min-classes.rs new file mode 100644 index 00000000000..f9a39e486da --- /dev/null +++ b/src/test/ui/max-min-classes.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/methods/auxiliary/method_self_arg1.rs b/src/test/ui/methods/auxiliary/method_self_arg1.rs new file mode 100644 index 00000000000..8258fdd9ab9 --- /dev/null +++ b/src/test/ui/methods/auxiliary/method_self_arg1.rs @@ -0,0 +1,37 @@ +#![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/src/test/ui/methods/auxiliary/method_self_arg2.rs b/src/test/ui/methods/auxiliary/method_self_arg2.rs new file mode 100644 index 00000000000..94a4a016c3e --- /dev/null +++ b/src/test/ui/methods/auxiliary/method_self_arg2.rs @@ -0,0 +1,54 @@ +#![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/src/test/ui/methods/method-argument-inference-associated-type.rs b/src/test/ui/methods/method-argument-inference-associated-type.rs new file mode 100644 index 00000000000..acd4a8465b0 --- /dev/null +++ b/src/test/ui/methods/method-argument-inference-associated-type.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/methods/method-early-bound-lifetimes-on-self.rs b/src/test/ui/methods/method-early-bound-lifetimes-on-self.rs new file mode 100644 index 00000000000..f2ace32c6b6 --- /dev/null +++ b/src/test/ui/methods/method-early-bound-lifetimes-on-self.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs new file mode 100644 index 00000000000..daff037b27b --- /dev/null +++ b/src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/methods/method-normalize-bounds-issue-20604.rs b/src/test/ui/methods/method-normalize-bounds-issue-20604.rs new file mode 100644 index 00000000000..9c0b952849e --- /dev/null +++ b/src/test/ui/methods/method-normalize-bounds-issue-20604.rs @@ -0,0 +1,61 @@ +// 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/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs new file mode 100644 index 00000000000..af362efe15c --- /dev/null +++ b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/methods/method-projection.rs b/src/test/ui/methods/method-projection.rs new file mode 100644 index 00000000000..cf33d53968b --- /dev/null +++ b/src/test/ui/methods/method-projection.rs @@ -0,0 +1,70 @@ +// 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/src/test/ui/methods/method-recursive-blanket-impl.rs b/src/test/ui/methods/method-recursive-blanket-impl.rs new file mode 100644 index 00000000000..a2db75b4e85 --- /dev/null +++ b/src/test/ui/methods/method-recursive-blanket-impl.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/methods/method-self-arg-aux1.rs b/src/test/ui/methods/method-self-arg-aux1.rs new file mode 100644 index 00000000000..9e38ff7de34 --- /dev/null +++ b/src/test/ui/methods/method-self-arg-aux1.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/methods/method-self-arg-aux2.rs b/src/test/ui/methods/method-self-arg-aux2.rs new file mode 100644 index 00000000000..8e70399d047 --- /dev/null +++ b/src/test/ui/methods/method-self-arg-aux2.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/methods/method-self-arg-trait.rs b/src/test/ui/methods/method-self-arg-trait.rs new file mode 100644 index 00000000000..227b1eab25d --- /dev/null +++ b/src/test/ui/methods/method-self-arg-trait.rs @@ -0,0 +1,69 @@ +// 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/src/test/ui/methods/method-self-arg.rs b/src/test/ui/methods/method-self-arg.rs new file mode 100644 index 00000000000..2d25b0dbad1 --- /dev/null +++ b/src/test/ui/methods/method-self-arg.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/methods/method-two-trait-defer-resolution-1.rs b/src/test/ui/methods/method-two-trait-defer-resolution-1.rs new file mode 100644 index 00000000000..b768620cd3a --- /dev/null +++ b/src/test/ui/methods/method-two-trait-defer-resolution-1.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/methods/method-two-trait-defer-resolution-2.rs b/src/test/ui/methods/method-two-trait-defer-resolution-2.rs new file mode 100644 index 00000000000..8af3dcf5c3d --- /dev/null +++ b/src/test/ui/methods/method-two-trait-defer-resolution-2.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs b/src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs new file mode 100644 index 00000000000..d820d2ad08a --- /dev/null +++ b/src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/methods/method-where-clause.rs b/src/test/ui/methods/method-where-clause.rs new file mode 100644 index 00000000000..01692abf9b6 --- /dev/null +++ b/src/test/ui/methods/method-where-clause.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/mid-path-type-params.rs b/src/test/ui/mid-path-type-params.rs new file mode 100644 index 00000000000..a8128207c80 --- /dev/null +++ b/src/test/ui/mid-path-type-params.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/minmax-stability-issue-23687.rs b/src/test/ui/minmax-stability-issue-23687.rs new file mode 100644 index 00000000000..9100bfbde95 --- /dev/null +++ b/src/test/ui/minmax-stability-issue-23687.rs @@ -0,0 +1,64 @@ +// 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/src/test/ui/mir/auxiliary/mir_external_refs.rs b/src/test/ui/mir/auxiliary/mir_external_refs.rs new file mode 100644 index 00000000000..9fd58f1d714 --- /dev/null +++ b/src/test/ui/mir/auxiliary/mir_external_refs.rs @@ -0,0 +1,17 @@ +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/src/test/ui/mir/mir-inlining/ice-issue-45493.rs b/src/test/ui/mir/mir-inlining/ice-issue-45493.rs new file mode 100644 index 00000000000..1bd16dc43e1 --- /dev/null +++ b/src/test/ui/mir/mir-inlining/ice-issue-45493.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/mir/mir-inlining/ice-issue-45885.rs b/src/test/ui/mir/mir-inlining/ice-issue-45885.rs new file mode 100644 index 00000000000..e930a4d1ccd --- /dev/null +++ b/src/test/ui/mir/mir-inlining/ice-issue-45885.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs b/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs new file mode 100644 index 00000000000..8f570dbd4ad --- /dev/null +++ b/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/mir/mir-typeck-normalize-fn-sig.rs b/src/test/ui/mir/mir-typeck-normalize-fn-sig.rs new file mode 100644 index 00000000000..bdd9321afd7 --- /dev/null +++ b/src/test/ui/mir/mir-typeck-normalize-fn-sig.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/mir/mir_adt_construction.rs b/src/test/ui/mir/mir_adt_construction.rs new file mode 100644 index 00000000000..9fb5896de6b --- /dev/null +++ b/src/test/ui/mir/mir_adt_construction.rs @@ -0,0 +1,92 @@ +// 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/src/test/ui/mir/mir_ascription_coercion.rs b/src/test/ui/mir/mir_ascription_coercion.rs new file mode 100644 index 00000000000..0ebd20e97d7 --- /dev/null +++ b/src/test/ui/mir/mir_ascription_coercion.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/mir/mir_augmented_assignments.rs b/src/test/ui/mir/mir_augmented_assignments.rs new file mode 100644 index 00000000000..44454f8f417 --- /dev/null +++ b/src/test/ui/mir/mir_augmented_assignments.rs @@ -0,0 +1,160 @@ +// 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/src/test/ui/mir/mir_autoderef.rs b/src/test/ui/mir/mir_autoderef.rs new file mode 100644 index 00000000000..a0e615a7387 --- /dev/null +++ b/src/test/ui/mir/mir_autoderef.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/mir/mir_boxing.rs b/src/test/ui/mir/mir_boxing.rs new file mode 100644 index 00000000000..83e1cfb640a --- /dev/null +++ b/src/test/ui/mir/mir_boxing.rs @@ -0,0 +1,10 @@ +// run-pass +#![feature(box_syntax)] + +fn test() -> Box { + box 42 +} + +fn main() { + assert_eq!(*test(), 42); +} diff --git a/src/test/ui/mir/mir_build_match_comparisons.rs b/src/test/ui/mir/mir_build_match_comparisons.rs new file mode 100644 index 00000000000..04570055763 --- /dev/null +++ b/src/test/ui/mir/mir_build_match_comparisons.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/mir/mir_call_with_associated_type.rs b/src/test/ui/mir/mir_call_with_associated_type.rs new file mode 100644 index 00000000000..7103533e1da --- /dev/null +++ b/src/test/ui/mir/mir_call_with_associated_type.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/mir/mir_calls_to_shims.rs b/src/test/ui/mir/mir_calls_to_shims.rs new file mode 100644 index 00000000000..6f13d5612ce --- /dev/null +++ b/src/test/ui/mir/mir_calls_to_shims.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/mir/mir_cast_fn_ret.rs b/src/test/ui/mir/mir_cast_fn_ret.rs new file mode 100644 index 00000000000..69fd64c1c09 --- /dev/null +++ b/src/test/ui/mir/mir_cast_fn_ret.rs @@ -0,0 +1,21 @@ +// run-pass +pub extern "C" fn tuple2() -> (u16, u8) { + (1, 2) +} + +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/src/test/ui/mir/mir_codegen_array.rs b/src/test/ui/mir/mir_codegen_array.rs new file mode 100644 index 00000000000..38e443d8e39 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_array.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/mir/mir_codegen_array_2.rs b/src/test/ui/mir/mir_codegen_array_2.rs new file mode 100644 index 00000000000..03d3aa5ade6 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_array_2.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/mir/mir_codegen_call_converging.rs b/src/test/ui/mir/mir_codegen_call_converging.rs new file mode 100644 index 00000000000..9c340e4e036 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_call_converging.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/mir/mir_codegen_calls.rs b/src/test/ui/mir/mir_codegen_calls.rs new file mode 100644 index 00000000000..fc0db03e3a9 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_calls.rs @@ -0,0 +1,191 @@ +// 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() +} + +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/src/test/ui/mir/mir_codegen_calls_variadic.rs b/src/test/ui/mir/mir_codegen_calls_variadic.rs new file mode 100644 index 00000000000..dc9fee03b77 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_calls_variadic.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/mir/mir_codegen_critical_edge.rs b/src/test/ui/mir/mir_codegen_critical_edge.rs new file mode 100644 index 00000000000..5c1f1c3b701 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_critical_edge.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/mir/mir_codegen_spike1.rs b/src/test/ui/mir/mir_codegen_spike1.rs new file mode 100644 index 00000000000..90bdd6b4bd7 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_spike1.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/mir/mir_codegen_switch.rs b/src/test/ui/mir/mir_codegen_switch.rs new file mode 100644 index 00000000000..d2589ae4ad2 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_switch.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/mir/mir_codegen_switchint.rs b/src/test/ui/mir/mir_codegen_switchint.rs new file mode 100644 index 00000000000..c092a6c31b2 --- /dev/null +++ b/src/test/ui/mir/mir_codegen_switchint.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/mir/mir_coercion_casts.rs b/src/test/ui/mir/mir_coercion_casts.rs new file mode 100644 index 00000000000..7d761181d80 --- /dev/null +++ b/src/test/ui/mir/mir_coercion_casts.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/mir/mir_coercions.rs b/src/test/ui/mir/mir_coercions.rs new file mode 100644 index 00000000000..f3dcc6b85fd --- /dev/null +++ b/src/test/ui/mir/mir_coercions.rs @@ -0,0 +1,71 @@ +// 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/src/test/ui/mir/mir_constval_adts.rs b/src/test/ui/mir/mir_constval_adts.rs new file mode 100644 index 00000000000..ee9d73451f4 --- /dev/null +++ b/src/test/ui/mir/mir_constval_adts.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs new file mode 100644 index 00000000000..2949437b1e4 --- /dev/null +++ b/src/test/ui/mir/mir_drop_order.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/mir/mir_early_return_scope.rs b/src/test/ui/mir/mir_early_return_scope.rs new file mode 100644 index 00000000000..a696471c361 --- /dev/null +++ b/src/test/ui/mir/mir_early_return_scope.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/mir/mir_fat_ptr.rs b/src/test/ui/mir/mir_fat_ptr.rs new file mode 100644 index 00000000000..fb34de62f31 --- /dev/null +++ b/src/test/ui/mir/mir_fat_ptr.rs @@ -0,0 +1,52 @@ +// 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/src/test/ui/mir/mir_fat_ptr_drop.rs b/src/test/ui/mir/mir_fat_ptr_drop.rs new file mode 100644 index 00000000000..d865c3499b2 --- /dev/null +++ b/src/test/ui/mir/mir_fat_ptr_drop.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/mir/mir_heavy_promoted.rs b/src/test/ui/mir/mir_heavy_promoted.rs new file mode 100644 index 00000000000..092299880e2 --- /dev/null +++ b/src/test/ui/mir/mir_heavy_promoted.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/mir/mir_match_arm_guard.rs b/src/test/ui/mir/mir_match_arm_guard.rs new file mode 100644 index 00000000000..65e4ed041bb --- /dev/null +++ b/src/test/ui/mir/mir_match_arm_guard.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/mir/mir_match_test.rs b/src/test/ui/mir/mir_match_test.rs new file mode 100644 index 00000000000..1f96d6737e0 --- /dev/null +++ b/src/test/ui/mir/mir_match_test.rs @@ -0,0 +1,83 @@ +#![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/src/test/ui/mir/mir_misc_casts.rs b/src/test/ui/mir/mir_misc_casts.rs new file mode 100644 index 00000000000..2e7fbeee5da --- /dev/null +++ b/src/test/ui/mir/mir_misc_casts.rs @@ -0,0 +1,320 @@ +// 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/src/test/ui/mir/mir_overflow_off.rs b/src/test/ui/mir/mir_overflow_off.rs new file mode 100644 index 00000000000..922ec36e531 --- /dev/null +++ b/src/test/ui/mir/mir_overflow_off.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/mir/mir_raw_fat_ptr.rs b/src/test/ui/mir/mir_raw_fat_ptr.rs new file mode 100644 index 00000000000..6583852aa9b --- /dev/null +++ b/src/test/ui/mir/mir_raw_fat_ptr.rs @@ -0,0 +1,158 @@ +// run-pass +// check raw fat pointer ops in mir +// FIXME: please improve this when we get monomorphization support + +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() { + 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 _)); +} diff --git a/src/test/ui/mir/mir_refs_correct.rs b/src/test/ui/mir/mir_refs_correct.rs new file mode 100644 index 00000000000..729db2d25f5 --- /dev/null +++ b/src/test/ui/mir/mir_refs_correct.rs @@ -0,0 +1,209 @@ +// 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/src/test/ui/mir/mir_small_agg_arg.rs b/src/test/ui/mir/mir_small_agg_arg.rs new file mode 100644 index 00000000000..5a22a0420c5 --- /dev/null +++ b/src/test/ui/mir/mir_small_agg_arg.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_variables)] +fn foo((x, y): (i8, i8)) { +} + +fn main() { + foo((0, 1)); +} diff --git a/src/test/ui/mir/mir_static_subtype.rs b/src/test/ui/mir/mir_static_subtype.rs new file mode 100644 index 00000000000..d471b8f149d --- /dev/null +++ b/src/test/ui/mir/mir_static_subtype.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/mir/mir_struct_with_assoc_ty.rs b/src/test/ui/mir/mir_struct_with_assoc_ty.rs new file mode 100644 index 00000000000..26d026bdfdd --- /dev/null +++ b/src/test/ui/mir/mir_struct_with_assoc_ty.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/mir/mir_temp_promotions.rs b/src/test/ui/mir/mir_temp_promotions.rs new file mode 100644 index 00000000000..845dc4c0444 --- /dev/null +++ b/src/test/ui/mir/mir_temp_promotions.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/mir/mir_void_return.rs b/src/test/ui/mir/mir_void_return.rs new file mode 100644 index 00000000000..d257affc268 --- /dev/null +++ b/src/test/ui/mir/mir_void_return.rs @@ -0,0 +1,12 @@ +// run-pass +fn mir() -> (){ + let x = 1; + let mut y = 0; + while y < x { + y += 1 + } +} + +pub fn main() { + mir(); +} diff --git a/src/test/ui/mir/mir_void_return_2.rs b/src/test/ui/mir/mir_void_return_2.rs new file mode 100644 index 00000000000..a1fb0a7db17 --- /dev/null +++ b/src/test/ui/mir/mir_void_return_2.rs @@ -0,0 +1,10 @@ +// run-pass +fn nil() {} + +fn mir(){ + nil() +} + +pub fn main() { + mir(); +} diff --git a/src/test/ui/modules/auxiliary/two_macros_2.rs b/src/test/ui/modules/auxiliary/two_macros_2.rs new file mode 100644 index 00000000000..8ad2c0f1275 --- /dev/null +++ b/src/test/ui/modules/auxiliary/two_macros_2.rs @@ -0,0 +1,3 @@ +macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } + +macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } diff --git a/src/test/ui/modules/mod-inside-fn.rs b/src/test/ui/modules/mod-inside-fn.rs new file mode 100644 index 00000000000..93050c8919a --- /dev/null +++ b/src/test/ui/modules/mod-inside-fn.rs @@ -0,0 +1,13 @@ +// run-pass + +fn f() -> isize { + mod m { + pub fn g() -> isize { 720 } + } + + m::g() +} + +pub fn main() { + assert_eq!(f(), 720); +} diff --git a/src/test/ui/modules/mod-view-items.rs b/src/test/ui/modules/mod-view-items.rs new file mode 100644 index 00000000000..db2b303668b --- /dev/null +++ b/src/test/ui/modules/mod-view-items.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/modules/mod_dir_implicit.rs b/src/test/ui/modules/mod_dir_implicit.rs new file mode 100644 index 00000000000..d6ea6a98bda --- /dev/null +++ b/src/test/ui/modules/mod_dir_implicit.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/modules/mod_dir_implicit_aux/compiletest-ignore-dir b/src/test/ui/modules/mod_dir_implicit_aux/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/modules/mod_dir_implicit_aux/mod.rs b/src/test/ui/modules/mod_dir_implicit_aux/mod.rs new file mode 100644 index 00000000000..4f1eb85e4cc --- /dev/null +++ b/src/test/ui/modules/mod_dir_implicit_aux/mod.rs @@ -0,0 +1,2 @@ +// run-pass +pub fn foo() -> isize { 10 } diff --git a/src/test/ui/modules/mod_dir_path.rs b/src/test/ui/modules/mod_dir_path.rs new file mode 100644 index 00000000000..70f592d0c0e --- /dev/null +++ b/src/test/ui/modules/mod_dir_path.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/modules/mod_dir_path2.rs b/src/test/ui/modules/mod_dir_path2.rs new file mode 100644 index 00000000000..c3e3e1d639e --- /dev/null +++ b/src/test/ui/modules/mod_dir_path2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/modules/mod_dir_path3.rs b/src/test/ui/modules/mod_dir_path3.rs new file mode 100644 index 00000000000..fed70c1bc98 --- /dev/null +++ b/src/test/ui/modules/mod_dir_path3.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/modules/mod_dir_path_multi.rs b/src/test/ui/modules/mod_dir_path_multi.rs new file mode 100644 index 00000000000..2b805141a63 --- /dev/null +++ b/src/test/ui/modules/mod_dir_path_multi.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/modules/mod_dir_recursive.rs b/src/test/ui/modules/mod_dir_recursive.rs new file mode 100644 index 00000000000..b109d13d164 --- /dev/null +++ b/src/test/ui/modules/mod_dir_recursive.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/modules/mod_dir_simple.rs b/src/test/ui/modules/mod_dir_simple.rs new file mode 100644 index 00000000000..1d92c968a8f --- /dev/null +++ b/src/test/ui/modules/mod_dir_simple.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/modules/mod_dir_simple/compiletest-ignore-dir b/src/test/ui/modules/mod_dir_simple/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/modules/mod_dir_simple/load_another_mod.rs b/src/test/ui/modules/mod_dir_simple/load_another_mod.rs new file mode 100644 index 00000000000..f96b546aa2f --- /dev/null +++ b/src/test/ui/modules/mod_dir_simple/load_another_mod.rs @@ -0,0 +1,3 @@ +// run-pass +#[path = "test.rs"] +pub mod test; diff --git a/src/test/ui/modules/mod_dir_simple/test.rs b/src/test/ui/modules/mod_dir_simple/test.rs new file mode 100644 index 00000000000..4f1eb85e4cc --- /dev/null +++ b/src/test/ui/modules/mod_dir_simple/test.rs @@ -0,0 +1,2 @@ +// run-pass +pub fn foo() -> isize { 10 } diff --git a/src/test/ui/modules/mod_file.rs b/src/test/ui/modules/mod_file.rs new file mode 100644 index 00000000000..0ca52889e5c --- /dev/null +++ b/src/test/ui/modules/mod_file.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/modules/mod_file_aux.rs b/src/test/ui/modules/mod_file_aux.rs new file mode 100644 index 00000000000..6d052272eb3 --- /dev/null +++ b/src/test/ui/modules/mod_file_aux.rs @@ -0,0 +1,4 @@ +// run-pass +// ignore-test Not a test. Used by other tests + +pub fn foo() -> isize { 10 } diff --git a/src/test/ui/modules/mod_file_with_path_attr.rs b/src/test/ui/modules/mod_file_with_path_attr.rs new file mode 100644 index 00000000000..48e253eadae --- /dev/null +++ b/src/test/ui/modules/mod_file_with_path_attr.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/modules/module-polymorphism3-files/compiletest-ignore-dir b/src/test/ui/modules/module-polymorphism3-files/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs new file mode 100644 index 00000000000..49d2b3d4b85 --- /dev/null +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs @@ -0,0 +1,3 @@ +// run-pass + +pub type T = f32; diff --git a/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs new file mode 100644 index 00000000000..e2aad480e3d --- /dev/null +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs @@ -0,0 +1,3 @@ +// run-pass + +pub type T = f64; diff --git a/src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs new file mode 100644 index 00000000000..5828718cddc --- /dev/null +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs @@ -0,0 +1,3 @@ +// run-pass + +pub type T = float; diff --git a/src/test/ui/monad.rs b/src/test/ui/monad.rs new file mode 100644 index 00000000000..5d0612cf8dc --- /dev/null +++ b/src/test/ui/monad.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/monomorphize-abi-alignment.rs b/src/test/ui/monomorphize-abi-alignment.rs new file mode 100644 index 00000000000..637b09fc04e --- /dev/null +++ b/src/test/ui/monomorphize-abi-alignment.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/monomorphized-callees-with-ty-params-3314.rs b/src/test/ui/monomorphized-callees-with-ty-params-3314.rs new file mode 100644 index 00000000000..bc314a39d8e --- /dev/null +++ b/src/test/ui/monomorphized-callees-with-ty-params-3314.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/moves/move-1-unique.rs b/src/test/ui/moves/move-1-unique.rs new file mode 100644 index 00000000000..48baead074a --- /dev/null +++ b/src/test/ui/moves/move-1-unique.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/moves/move-2-unique.rs b/src/test/ui/moves/move-2-unique.rs new file mode 100644 index 00000000000..910a88c102f --- /dev/null +++ b/src/test/ui/moves/move-2-unique.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/moves/move-2.rs b/src/test/ui/moves/move-2.rs new file mode 100644 index 00000000000..4ad53e96e50 --- /dev/null +++ b/src/test/ui/moves/move-2.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/moves/move-3-unique.rs b/src/test/ui/moves/move-3-unique.rs new file mode 100644 index 00000000000..55b10e057d8 --- /dev/null +++ b/src/test/ui/moves/move-3-unique.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/moves/move-4-unique.rs b/src/test/ui/moves/move-4-unique.rs new file mode 100644 index 00000000000..1787caadb7a --- /dev/null +++ b/src/test/ui/moves/move-4-unique.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/moves/move-4.rs b/src/test/ui/moves/move-4.rs new file mode 100644 index 00000000000..c87c605df77 --- /dev/null +++ b/src/test/ui/moves/move-4.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/moves/move-arg-2-unique.rs b/src/test/ui/moves/move-arg-2-unique.rs new file mode 100644 index 00000000000..fcfd5e14765 --- /dev/null +++ b/src/test/ui/moves/move-arg-2-unique.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/moves/move-arg-2.rs b/src/test/ui/moves/move-arg-2.rs new file mode 100644 index 00000000000..4cd1f6fe810 --- /dev/null +++ b/src/test/ui/moves/move-arg-2.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/moves/move-arg.rs b/src/test/ui/moves/move-arg.rs new file mode 100644 index 00000000000..5942cd89fd9 --- /dev/null +++ b/src/test/ui/moves/move-arg.rs @@ -0,0 +1,5 @@ +// run-pass + +fn test(foo: isize) { assert_eq!(foo, 10); } + +pub fn main() { let x = 10; test(x); } diff --git a/src/test/ui/moves/move-nullary-fn.rs b/src/test/ui/moves/move-nullary-fn.rs new file mode 100644 index 00000000000..14c9262c74d --- /dev/null +++ b/src/test/ui/moves/move-nullary-fn.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/moves/move-out-of-field.rs b/src/test/ui/moves/move-out-of-field.rs new file mode 100644 index 00000000000..9f697db4f79 --- /dev/null +++ b/src/test/ui/moves/move-out-of-field.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/moves/move-scalar.rs b/src/test/ui/moves/move-scalar.rs new file mode 100644 index 00000000000..98bfeb1bc05 --- /dev/null +++ b/src/test/ui/moves/move-scalar.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/moves/moves-based-on-type-capture-clause.rs b/src/test/ui/moves/moves-based-on-type-capture-clause.rs new file mode 100644 index 00000000000..4a6a4ed281d --- /dev/null +++ b/src/test/ui/moves/moves-based-on-type-capture-clause.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/mpsc_stress.rs b/src/test/ui/mpsc_stress.rs new file mode 100644 index 00000000000..bce5fdcd119 --- /dev/null +++ b/src/test/ui/mpsc_stress.rs @@ -0,0 +1,164 @@ +// run-pass +// compile-flags:--test +// ignore-emscripten +// ignore-sgx no thread sleep support + +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 { + } + } +} + + +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/src/test/ui/msvc-data-only.rs b/src/test/ui/msvc-data-only.rs new file mode 100644 index 00000000000..f668b0b0682 --- /dev/null +++ b/src/test/ui/msvc-data-only.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/multi-panic.rs b/src/test/ui/multi-panic.rs new file mode 100644 index 00000000000..e4b41e41806 --- /dev/null +++ b/src/test/ui/multi-panic.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/multibyte.rs b/src/test/ui/multibyte.rs new file mode 100644 index 00000000000..7e3a577f9f2 --- /dev/null +++ b/src/test/ui/multibyte.rs @@ -0,0 +1,7 @@ +// run-pass +// + +// Test that multibyte characters don't crash the compiler +pub fn main() { + println!("마이너스 사인이 없으면"); +} diff --git a/src/test/ui/multidispatch-conditional-impl-not-considered.rs b/src/test/ui/multidispatch-conditional-impl-not-considered.rs new file mode 100644 index 00000000000..f845e198aa5 --- /dev/null +++ b/src/test/ui/multidispatch-conditional-impl-not-considered.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/multidispatch1.rs b/src/test/ui/multidispatch1.rs new file mode 100644 index 00000000000..f2469e1490e --- /dev/null +++ b/src/test/ui/multidispatch1.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/multidispatch2.rs b/src/test/ui/multidispatch2.rs new file mode 100644 index 00000000000..20608aabb3b --- /dev/null +++ b/src/test/ui/multidispatch2.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/multiline-comment.rs b/src/test/ui/multiline-comment.rs new file mode 100644 index 00000000000..01aaac28232 --- /dev/null +++ b/src/test/ui/multiline-comment.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* + * This is a multi-line oldcomment. + */ +pub fn main() { } diff --git a/src/test/ui/multiple-reprs.rs b/src/test/ui/multiple-reprs.rs new file mode 100644 index 00000000000..4be503a0ef4 --- /dev/null +++ b/src/test/ui/multiple-reprs.rs @@ -0,0 +1,82 @@ +// 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/src/test/ui/mut-function-arguments.rs b/src/test/ui/mut-function-arguments.rs new file mode 100644 index 00000000000..620d00edbbc --- /dev/null +++ b/src/test/ui/mut-function-arguments.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/mut-vstore-expr.rs b/src/test/ui/mut-vstore-expr.rs new file mode 100644 index 00000000000..75b309a4839 --- /dev/null +++ b/src/test/ui/mut-vstore-expr.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let _x: &mut [isize] = &mut [ 1, 2, 3 ]; +} diff --git a/src/test/ui/mutual-recursion-group.rs b/src/test/ui/mutual-recursion-group.rs new file mode 100644 index 00000000000..86b0f1d840e --- /dev/null +++ b/src/test/ui/mutual-recursion-group.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/native-print-no-runtime.rs b/src/test/ui/native-print-no-runtime.rs new file mode 100644 index 00000000000..f17c9fa6ca9 --- /dev/null +++ b/src/test/ui/native-print-no-runtime.rs @@ -0,0 +1,9 @@ +// run-pass + +#![feature(start)] + +#[start] +pub fn main(_: isize, _: *const *const u8) -> isize { + println!("hello"); + 0 +} diff --git a/src/test/ui/negative.rs b/src/test/ui/negative.rs new file mode 100644 index 00000000000..9601e9118aa --- /dev/null +++ b/src/test/ui/negative.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + match -5 { + -5 => {} + _ => { panic!() } + } +} diff --git a/src/test/ui/nested-block-comment.rs b/src/test/ui/nested-block-comment.rs new file mode 100644 index 00000000000..f8dfb5fa8ca --- /dev/null +++ b/src/test/ui/nested-block-comment.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* This test checks that nested comments are supported + + /* + This should not panic + */ +*/ + +pub fn main() { +} diff --git a/src/test/ui/nested-class.rs b/src/test/ui/nested-class.rs new file mode 100644 index 00000000000..303273618e1 --- /dev/null +++ b/src/test/ui/nested-class.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/nested-function-names-issue-8587.rs b/src/test/ui/nested-function-names-issue-8587.rs new file mode 100644 index 00000000000..8fafd41d9bc --- /dev/null +++ b/src/test/ui/nested-function-names-issue-8587.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/nested_item_main.rs b/src/test/ui/nested_item_main.rs new file mode 100644 index 00000000000..2fe00aede00 --- /dev/null +++ b/src/test/ui/nested_item_main.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/never-result.rs b/src/test/ui/never-result.rs new file mode 100644 index 00000000000..98ce326aa66 --- /dev/null +++ b/src/test/ui/never-result.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/never-type-rvalues.rs b/src/test/ui/never-type-rvalues.rs new file mode 100644 index 00000000000..9ccc73dbf92 --- /dev/null +++ b/src/test/ui/never-type-rvalues.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/never_coercions.rs b/src/test/ui/never_coercions.rs new file mode 100644 index 00000000000..105c3863533 --- /dev/null +++ b/src/test/ui/never_coercions.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/new-box-syntax.rs b/src/test/ui/new-box-syntax.rs new file mode 100644 index 00000000000..418cf554b49 --- /dev/null +++ b/src/test/ui/new-box-syntax.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/new-box.rs b/src/test/ui/new-box.rs new file mode 100644 index 00000000000..d11f0d045a7 --- /dev/null +++ b/src/test/ui/new-box.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/new-impl-syntax.rs b/src/test/ui/new-impl-syntax.rs new file mode 100644 index 00000000000..e1f2bea9afa --- /dev/null +++ b/src/test/ui/new-impl-syntax.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/new-import-syntax.rs b/src/test/ui/new-import-syntax.rs new file mode 100644 index 00000000000..f132ed57ce9 --- /dev/null +++ b/src/test/ui/new-import-syntax.rs @@ -0,0 +1,5 @@ +// run-pass + +pub fn main() { + println!("Hello world!"); +} diff --git a/src/test/ui/new-style-constants.rs b/src/test/ui/new-style-constants.rs new file mode 100644 index 00000000000..82ed7b55740 --- /dev/null +++ b/src/test/ui/new-style-constants.rs @@ -0,0 +1,7 @@ +// run-pass + +static FOO: isize = 3; + +pub fn main() { + println!("{}", FOO); +} diff --git a/src/test/ui/new-unicode-escapes.rs b/src/test/ui/new-unicode-escapes.rs new file mode 100644 index 00000000000..850b0de44b7 --- /dev/null +++ b/src/test/ui/new-unicode-escapes.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/new-unsafe-pointers.rs b/src/test/ui/new-unsafe-pointers.rs new file mode 100644 index 00000000000..d99eb4cbd1c --- /dev/null +++ b/src/test/ui/new-unsafe-pointers.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/newlambdas-ret-infer.rs b/src/test/ui/newlambdas-ret-infer.rs new file mode 100644 index 00000000000..9b629838ffd --- /dev/null +++ b/src/test/ui/newlambdas-ret-infer.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/newlambdas-ret-infer2.rs b/src/test/ui/newlambdas-ret-infer2.rs new file mode 100644 index 00000000000..abe31a05f22 --- /dev/null +++ b/src/test/ui/newlambdas-ret-infer2.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/newlambdas.rs b/src/test/ui/newlambdas.rs new file mode 100644 index 00000000000..90de53856c0 --- /dev/null +++ b/src/test/ui/newlambdas.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/newtype-polymorphic.rs b/src/test/ui/newtype-polymorphic.rs new file mode 100644 index 00000000000..a6a725211ad --- /dev/null +++ b/src/test/ui/newtype-polymorphic.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/newtype-temporary.rs b/src/test/ui/newtype-temporary.rs new file mode 100644 index 00000000000..8ee75b2fef1 --- /dev/null +++ b/src/test/ui/newtype-temporary.rs @@ -0,0 +1,12 @@ +// run-pass + +#[derive(PartialEq, Debug)] +struct Foo(usize); + +fn foo() -> Foo { + Foo(42) +} + +pub fn main() { + assert_eq!(foo(), Foo(42)); +} diff --git a/src/test/ui/newtype.rs b/src/test/ui/newtype.rs new file mode 100644 index 00000000000..f02b66f450f --- /dev/null +++ b/src/test/ui/newtype.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/nil-decl-in-foreign.rs b/src/test/ui/nil-decl-in-foreign.rs new file mode 100644 index 00000000000..98422665b9c --- /dev/null +++ b/src/test/ui/nil-decl-in-foreign.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/nll/issue-47153-generic-const.rs b/src/test/ui/nll/issue-47153-generic-const.rs new file mode 100644 index 00000000000..9f4d57111bb --- /dev/null +++ b/src/test/ui/nll/issue-47153-generic-const.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/nll/issue-47589.rs b/src/test/ui/nll/issue-47589.rs new file mode 100644 index 00000000000..280bf081138 --- /dev/null +++ b/src/test/ui/nll/issue-47589.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/nll/issue-48623-closure.rs b/src/test/ui/nll/issue-48623-closure.rs new file mode 100644 index 00000000000..3f8587eed41 --- /dev/null +++ b/src/test/ui/nll/issue-48623-closure.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/nll/issue-48623-generator.rs b/src/test/ui/nll/issue-48623-generator.rs new file mode 100644 index 00000000000..ba3eccff495 --- /dev/null +++ b/src/test/ui/nll/issue-48623-generator.rs @@ -0,0 +1,18 @@ +// 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 }; +} + +fn main() {} diff --git a/src/test/ui/nll/issue-50343.rs b/src/test/ui/nll/issue-50343.rs new file mode 100644 index 00000000000..55a2d231e19 --- /dev/null +++ b/src/test/ui/nll/issue-50343.rs @@ -0,0 +1,8 @@ +// run-pass + +#![deny(unused_mut)] + +fn main() { + vec![42].iter().map(|_| ()).count(); + vec![(42, 22)].iter().map(|(_x, _y)| ()).count(); +} diff --git a/src/test/ui/nll/issue-50461-used-mut-from-moves.rs b/src/test/ui/nll/issue-50461-used-mut-from-moves.rs new file mode 100644 index 00000000000..69d7cdd83a6 --- /dev/null +++ b/src/test/ui/nll/issue-50461-used-mut-from-moves.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/nll/issue-53123-raw-pointer-cast.rs b/src/test/ui/nll/issue-53123-raw-pointer-cast.rs new file mode 100644 index 00000000000..941c9eeb411 --- /dev/null +++ b/src/test/ui/nll/issue-53123-raw-pointer-cast.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/nll/mutating_references.rs b/src/test/ui/nll/mutating_references.rs new file mode 100644 index 00000000000..eb46b30b6b9 --- /dev/null +++ b/src/test/ui/nll/mutating_references.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/nll/process_or_insert_default.rs b/src/test/ui/nll/process_or_insert_default.rs new file mode 100644 index 00000000000..84ac9bbd0dd --- /dev/null +++ b/src/test/ui/nll/process_or_insert_default.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/nll/rc-loop.rs b/src/test/ui/nll/rc-loop.rs new file mode 100644 index 00000000000..e59303d1f78 --- /dev/null +++ b/src/test/ui/nll/rc-loop.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/no-core-1.rs b/src/test/ui/no-core-1.rs new file mode 100644 index 00000000000..9374f546ac9 --- /dev/null +++ b/src/test/ui/no-core-1.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/no-core-2.rs b/src/test/ui/no-core-2.rs new file mode 100644 index 00000000000..b08e63dc7cf --- /dev/null +++ b/src/test/ui/no-core-2.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/no-landing-pads.rs b/src/test/ui/no-landing-pads.rs new file mode 100644 index 00000000000..d9d53210612 --- /dev/null +++ b/src/test/ui/no-landing-pads.rs @@ -0,0 +1,23 @@ +// run-pass +// compile-flags: -Z no-landing-pads -C codegen-units=1 +// ignore-emscripten no threads support + +use std::thread; + +static mut HIT: bool = false; + +struct A; + +impl Drop for A { + fn drop(&mut self) { + unsafe { HIT = true; } + } +} + +fn main() { + thread::spawn(move|| -> () { + let _a = A; + panic!(); + }).join().unwrap_err(); + assert!(unsafe { !HIT }); +} diff --git a/src/test/ui/no-std-1.rs b/src/test/ui/no-std-1.rs new file mode 100644 index 00000000000..5b59e9b4eb3 --- /dev/null +++ b/src/test/ui/no-std-1.rs @@ -0,0 +1,10 @@ +// run-pass + +#![no_std] + +extern crate std; + +fn main() { + let a = Some("foo"); + a.unwrap(); +} diff --git a/src/test/ui/no-std-2.rs b/src/test/ui/no-std-2.rs new file mode 100644 index 00000000000..487d41649f4 --- /dev/null +++ b/src/test/ui/no-std-2.rs @@ -0,0 +1,10 @@ +// run-pass + +#![no_std] + +extern crate std; + +fn main() { + let a = core::option::Option::Some("foo"); + a.unwrap(); +} diff --git a/src/test/ui/no-std-3.rs b/src/test/ui/no-std-3.rs new file mode 100644 index 00000000000..f6c4ed5794c --- /dev/null +++ b/src/test/ui/no-std-3.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/no-stdio.rs b/src/test/ui/no-stdio.rs new file mode 100644 index 00000000000..e72b7b26e22 --- /dev/null +++ b/src/test/ui/no-stdio.rs @@ -0,0 +1,120 @@ +// 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(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 { + println!("test"); + assert!(io::stdout().write(b"test\n").is_ok()); + assert!(io::stderr().write(b"test\n").is_ok()); + assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); + 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/src/test/ui/non-built-in-quote.rs b/src/test/ui/non-built-in-quote.rs new file mode 100644 index 00000000000..92efa99e396 --- /dev/null +++ b/src/test/ui/non-built-in-quote.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +macro_rules! quote_tokens { () => (()) } + +pub fn main() { + quote_tokens!(); +} diff --git a/src/test/ui/non-legacy-modes.rs b/src/test/ui/non-legacy-modes.rs new file mode 100644 index 00000000000..38c83e00a6a --- /dev/null +++ b/src/test/ui/non-legacy-modes.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/non_modrs_mods/foors_mod.rs b/src/test/ui/non_modrs_mods/foors_mod.rs new file mode 100644 index 00000000000..5bf35fbf7fb --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/non_modrs_mods/foors_mod/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/foors_mod/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs b/src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs new file mode 100644 index 00000000000..4d8eb350bd2 --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod innest; diff --git a/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..4d8eb350bd2 --- /dev/null +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod innest; diff --git a/src/test/ui/non_modrs_mods/modrs_mod/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/modrs_mod/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs b/src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs new file mode 100644 index 00000000000..4d8eb350bd2 --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod innest; diff --git a/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..4d8eb350bd2 --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod innest; diff --git a/src/test/ui/non_modrs_mods/modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/mod.rs new file mode 100644 index 00000000000..c8efa66d665 --- /dev/null +++ b/src/test/ui/non_modrs_mods/modrs_mod/mod.rs @@ -0,0 +1,8 @@ +// run-pass + +pub mod inner_modrs_mod; +pub mod inner_foors_mod; +pub mod inline { + #[path="somename.rs"] + pub mod innie; +} diff --git a/src/test/ui/non_modrs_mods/non_modrs_mods.rs b/src/test/ui/non_modrs_mods/non_modrs_mods.rs new file mode 100644 index 00000000000..f664b0166d8 --- /dev/null +++ b/src/test/ui/non_modrs_mods/non_modrs_mods.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs new file mode 100644 index 00000000000..7d5d5b9e5ca --- /dev/null +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod inner_modrs_mod; diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..04585f918fd --- /dev/null +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..4d8eb350bd2 --- /dev/null +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs @@ -0,0 +1,3 @@ +// run-pass + +pub mod innest; diff --git a/src/test/ui/nul-characters.rs b/src/test/ui/nul-characters.rs new file mode 100644 index 00000000000..11b6e9fe376 --- /dev/null +++ b/src/test/ui/nul-characters.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/nullable-pointer-ffi-compat.rs b/src/test/ui/nullable-pointer-ffi-compat.rs new file mode 100644 index 00000000000..0647a18c3c4 --- /dev/null +++ b/src/test/ui/nullable-pointer-ffi-compat.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/nullable-pointer-iotareduction.rs b/src/test/ui/nullable-pointer-iotareduction.rs new file mode 100644 index 00000000000..4c6964f294b --- /dev/null +++ b/src/test/ui/nullable-pointer-iotareduction.rs @@ -0,0 +1,73 @@ +// 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/src/test/ui/nullable-pointer-size.rs b/src/test/ui/nullable-pointer-size.rs new file mode 100644 index 00000000000..63a106f1292 --- /dev/null +++ b/src/test/ui/nullable-pointer-size.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/numbers-arithmetic/arith-0.rs b/src/test/ui/numbers-arithmetic/arith-0.rs new file mode 100644 index 00000000000..7943cb908d1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-0.rs @@ -0,0 +1,8 @@ +// run-pass + + +pub fn main() { + let a: isize = 10; + println!("{}", a); + assert_eq!(a * (a - 1), 90); +} diff --git a/src/test/ui/numbers-arithmetic/arith-1.rs b/src/test/ui/numbers-arithmetic/arith-1.rs new file mode 100644 index 00000000000..c13c8d8b765 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-1.rs @@ -0,0 +1,24 @@ +// run-pass + + +pub fn main() { + let i32_a: isize = 10; + assert_eq!(i32_a, 10); + assert_eq!(i32_a - 10, 0); + assert_eq!(i32_a / 10, 1); + assert_eq!(i32_a - 20, -10); + assert_eq!(i32_a << 10, 10240); + assert_eq!(i32_a << 16, 655360); + assert_eq!(i32_a * 16, 160); + assert_eq!(i32_a * i32_a * i32_a, 1000); + assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000); + assert_eq!(i32_a * i32_a / i32_a * i32_a, 100); + assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640); + let i32_b: isize = 0x10101010; + assert_eq!(i32_b + 1 - 1, i32_b); + assert_eq!(i32_b << 1, i32_b << 1); + assert_eq!(i32_b >> 1, i32_b >> 1); + assert_eq!(i32_b & i32_b << 1, 0); + println!("{}", i32_b | i32_b << 1); + assert_eq!(i32_b | i32_b << 1, 0x30303030); +} diff --git a/src/test/ui/numbers-arithmetic/arith-2.rs b/src/test/ui/numbers-arithmetic/arith-2.rs new file mode 100644 index 00000000000..46c280677ce --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-2.rs @@ -0,0 +1,9 @@ +// run-pass + + + +pub fn main() { + let i32_c: isize = 0x10101010; + assert_eq!(i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3), + i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3)); +} diff --git a/src/test/ui/numbers-arithmetic/arith-unsigned.rs b/src/test/ui/numbers-arithmetic/arith-unsigned.rs new file mode 100644 index 00000000000..ad57d9f8645 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-unsigned.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/numbers-arithmetic/div-mod.rs b/src/test/ui/numbers-arithmetic/div-mod.rs new file mode 100644 index 00000000000..acb92a7df73 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/div-mod.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs new file mode 100644 index 00000000000..d210abdf499 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs @@ -0,0 +1,53 @@ +// run-pass +// ignore-emscripten no i128 support + +#![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/src/test/ui/numbers-arithmetic/float-literal-inference.rs b/src/test/ui/numbers-arithmetic/float-literal-inference.rs new file mode 100644 index 00000000000..c4645e4f8ff --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-literal-inference.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/numbers-arithmetic/float-nan.rs b/src/test/ui/numbers-arithmetic/float-nan.rs new file mode 100644 index 00000000000..ee87b8cccfe --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-nan.rs @@ -0,0 +1,83 @@ +// 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/src/test/ui/numbers-arithmetic/float-signature.rs b/src/test/ui/numbers-arithmetic/float-signature.rs new file mode 100644 index 00000000000..d47280ea2e7 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-signature.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/numbers-arithmetic/float.rs b/src/test/ui/numbers-arithmetic/float.rs new file mode 100644 index 00000000000..d55c05857b6 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/numbers-arithmetic/float2.rs b/src/test/ui/numbers-arithmetic/float2.rs new file mode 100644 index 00000000000..b1bcf8da5a3 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float2.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/numbers-arithmetic/float_math.rs b/src/test/ui/numbers-arithmetic/float_math.rs new file mode 100644 index 00000000000..a2902ee5608 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float_math.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/numbers-arithmetic/floatlits.rs b/src/test/ui/numbers-arithmetic/floatlits.rs new file mode 100644 index 00000000000..07049af315b --- /dev/null +++ b/src/test/ui/numbers-arithmetic/floatlits.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/numbers-arithmetic/i128-ffi.rs b/src/test/ui/numbers-arithmetic/i128-ffi.rs new file mode 100644 index 00000000000..19edf9779f3 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i128-ffi.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/numbers-arithmetic/i128.rs b/src/test/ui/numbers-arithmetic/i128.rs new file mode 100644 index 00000000000..ea0ef95e4f1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i128.rs @@ -0,0 +1,110 @@ +// run-pass +#![allow(overflowing_literals)] + +// ignore-emscripten i128 doesn't work + + +#![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_value()); + 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/src/test/ui/numbers-arithmetic/i32-sub.rs b/src/test/ui/numbers-arithmetic/i32-sub.rs new file mode 100644 index 00000000000..56df772b4e1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i32-sub.rs @@ -0,0 +1,6 @@ +// run-pass + + + + +pub fn main() { let mut x: i32 = -400; x = 0 - x; assert_eq!(x, 400); } diff --git a/src/test/ui/numbers-arithmetic/i8-incr.rs b/src/test/ui/numbers-arithmetic/i8-incr.rs new file mode 100644 index 00000000000..718d259f735 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i8-incr.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs new file mode 100644 index 00000000000..2bc018445db --- /dev/null +++ b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags: -Z force-overflow-checks=on +// ignore-emscripten no threads support + +use std::thread; + +fn main() { + assert!(thread::spawn(|| i8::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i16::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i32::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i64::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| isize::min_value().abs()).join().is_err()); +} diff --git a/src/test/ui/numbers-arithmetic/int.rs b/src/test/ui/numbers-arithmetic/int.rs new file mode 100644 index 00000000000..b496a70a6fe --- /dev/null +++ b/src/test/ui/numbers-arithmetic/int.rs @@ -0,0 +1,7 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: isize = 10; } diff --git a/src/test/ui/numbers-arithmetic/integer-literal-radix.rs b/src/test/ui/numbers-arithmetic/integer-literal-radix.rs new file mode 100644 index 00000000000..8f61ea17a12 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-radix.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs new file mode 100644 index 00000000000..80248dc223d --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn foo(_: *const ()) {} + +fn main() { + let a = 3; + foo(&a as *const _ as *const ()); +} diff --git a/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs new file mode 100644 index 00000000000..bec718a3c6a --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + println!("{}", std::mem::size_of_val(&1)); +} diff --git a/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs new file mode 100644 index 00000000000..d177ced1a69 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs new file mode 100644 index 00000000000..e9927304f23 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs @@ -0,0 +1,27 @@ +// 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_value()).next_power_of_two() + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + (($t::max_value() >> 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/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs new file mode 100644 index 00000000000..982cd97c50a --- /dev/null +++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/numbers-arithmetic/num-wrapping.rs b/src/test/ui/numbers-arithmetic/num-wrapping.rs new file mode 100644 index 00000000000..9a01549ecd2 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/num-wrapping.rs @@ -0,0 +1,447 @@ +// 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/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs b/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs new file mode 100644 index 00000000000..5798c2591a0 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs new file mode 100644 index 00000000000..a3b8ff58a73 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(const_err)] + +// compile-flags: -O + +fn main() { + let x = &(0u32 - 1); + assert_eq!(*x, u32::max_value()) +} diff --git a/src/test/ui/numbers-arithmetic/saturating-float-casts.rs b/src/test/ui/numbers-arithmetic/saturating-float-casts.rs new file mode 100644 index 00000000000..f13964fb386 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/saturating-float-casts.rs @@ -0,0 +1,135 @@ +// run-pass +// Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. +// compile-flags: -Z saturating-float-casts + +#![feature(test, stmt_expr_attributes)] +#![deny(overflowing_literals)] +extern crate test; + +use std::{f32, f64}; +use std::{u8, i8, u16, i16, u32, i32, u64, i64}; +#[cfg(not(target_os="emscripten"))] +use std::{u128, i128}; +use test::black_box; + +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)); + ); + + ($fval:expr, f* -> $ity:ident, $ival:expr) => ( + test!($fval, f32 -> $ity, $ival); + test!($fval, f64 -> $ity, $ival); + ) +} + +// This macro tests const eval in addition to run-time evaluation. +// If and when saturating casts are adopted, this macro should be merged with test!() to ensure +// that run-time and const eval agree on inputs that currently trigger a const eval error. +macro_rules! test_c { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ + test!($val, $src_ty -> $dest_ty, $expected); + { + 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_c!($fval, f32 -> $ity, $ival); + test_c!($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_c!(0., $fty -> $ity, 0); + test_c!($fty::MIN_POSITIVE, $fty -> $ity, 0); + test!(-0.9, $fty -> $ity, 0); + test_c!(1., $fty -> $ity, 1); + test_c!(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)+); + }) +} + +pub fn main() { + 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_c!(254., f* -> u8, 254); + test!(256., f* -> u8, 255); + + // # i8 + test_c!(-127., f* -> i8, -127); + test!(-129., f* -> i8, -128); + test_c!(126., f* -> i8, 126); + test!(128., f* -> i8, 127); + + // # i32 + // -2147483648. is i32::MIN (exactly) + test_c!(-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_c!(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_c!(-2147483520., f* -> i32, -2147483520); + + // # u32 + // round(MAX) and nextUp(round(MAX)) + test_c!(4294967040., f* -> u32, 4294967040); + test!(4294967296., f* -> u32, 4294967295); + + // # u128 + #[cfg(not(target_os="emscripten"))] + { + // float->int: + test_c!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000); + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; + test_c!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000); + } +} diff --git a/src/test/ui/numbers-arithmetic/shift-near-oflo.rs b/src/test/ui/numbers-arithmetic/shift-near-oflo.rs new file mode 100644 index 00000000000..939eb974612 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift-near-oflo.rs @@ -0,0 +1,100 @@ +// 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/src/test/ui/numbers-arithmetic/shift-various-types.rs b/src/test/ui/numbers-arithmetic/shift-various-types.rs new file mode 100644 index 00000000000..473bda3d76e --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift-various-types.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/numbers-arithmetic/shift.rs b/src/test/ui/numbers-arithmetic/shift.rs new file mode 100644 index 00000000000..2fc77928ef1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift.rs @@ -0,0 +1,76 @@ +// 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/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs b/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs new file mode 100644 index 00000000000..6d0462b460e --- /dev/null +++ b/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/numbers-arithmetic/u128-as-f32.rs b/src/test/ui/numbers-arithmetic/u128-as-f32.rs new file mode 100644 index 00000000000..bef7deb6276 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u128-as-f32.rs @@ -0,0 +1,49 @@ +// run-pass +// ignore-emscripten u128 not supported + +#![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/src/test/ui/numbers-arithmetic/u128.rs b/src/test/ui/numbers-arithmetic/u128.rs new file mode 100644 index 00000000000..93940716323 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u128.rs @@ -0,0 +1,121 @@ +// run-pass +// ignore-emscripten u128 not supported + + +#![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_value())); + 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_value() - 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/src/test/ui/numbers-arithmetic/u32-decr.rs b/src/test/ui/numbers-arithmetic/u32-decr.rs new file mode 100644 index 00000000000..d9e09781877 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u32-decr.rs @@ -0,0 +1,10 @@ +// run-pass + + + + +pub fn main() { + let mut word: u32 = 200000; + word = word - 1; + assert_eq!(word, 199999); +} diff --git a/src/test/ui/numbers-arithmetic/u8-incr-decr.rs b/src/test/ui/numbers-arithmetic/u8-incr-decr.rs new file mode 100644 index 00000000000..b16ec011d06 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u8-incr-decr.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/numbers-arithmetic/u8-incr.rs b/src/test/ui/numbers-arithmetic/u8-incr.rs new file mode 100644 index 00000000000..5242acf5b98 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u8-incr.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/numbers-arithmetic/uint.rs b/src/test/ui/numbers-arithmetic/uint.rs new file mode 100644 index 00000000000..d219eae8f33 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/uint.rs @@ -0,0 +1,7 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: usize = 10 as usize; } diff --git a/src/test/ui/object-lifetime-default-default-to-static.rs b/src/test/ui/object-lifetime-default-default-to-static.rs new file mode 100644 index 00000000000..467767ae59d --- /dev/null +++ b/src/test/ui/object-lifetime-default-default-to-static.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/object-lifetime-default-from-rptr-box.rs b/src/test/ui/object-lifetime-default-from-rptr-box.rs new file mode 100644 index 00000000000..8ac45b3db71 --- /dev/null +++ b/src/test/ui/object-lifetime-default-from-rptr-box.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/object-lifetime-default-from-rptr-mut.rs b/src/test/ui/object-lifetime-default-from-rptr-mut.rs new file mode 100644 index 00000000000..a09fc03ab9b --- /dev/null +++ b/src/test/ui/object-lifetime-default-from-rptr-mut.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/object-lifetime-default-from-rptr.rs b/src/test/ui/object-lifetime-default-from-rptr.rs new file mode 100644 index 00000000000..5093b1c27d0 --- /dev/null +++ b/src/test/ui/object-lifetime-default-from-rptr.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/object-method-numbering.rs b/src/test/ui/object-method-numbering.rs new file mode 100644 index 00000000000..bf80a80f406 --- /dev/null +++ b/src/test/ui/object-method-numbering.rs @@ -0,0 +1,28 @@ +// run-pass +// Test for using an object with an associated type binding as the +// instantiation for a generic type with a bound. + + +trait SomeTrait { + type SomeType; + + fn get(&self) -> Self::SomeType; +} + +fn get_int+?Sized>(x: &T) -> i32 { + x.get() +} + +impl SomeTrait for i32 { + type SomeType = i32; + fn get(&self) -> i32 { + *self + } +} + +fn main() { + let x = 22; + let x1: &dyn SomeTrait = &x; + let y = get_int(x1); + assert_eq!(x, y); +} diff --git a/src/test/ui/objects-coerce-freeze-borrored.rs b/src/test/ui/objects-coerce-freeze-borrored.rs new file mode 100644 index 00000000000..704d77480b8 --- /dev/null +++ b/src/test/ui/objects-coerce-freeze-borrored.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/objects-owned-object-borrowed-method-headerless.rs b/src/test/ui/objects-owned-object-borrowed-method-headerless.rs new file mode 100644 index 00000000000..9b88d8ea7bc --- /dev/null +++ b/src/test/ui/objects-owned-object-borrowed-method-headerless.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/objects-owned-object-owned-method.rs b/src/test/ui/objects-owned-object-owned-method.rs new file mode 100644 index 00000000000..4b7b68f2217 --- /dev/null +++ b/src/test/ui/objects-owned-object-owned-method.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/once-move-out-on-heap.rs b/src/test/ui/once-move-out-on-heap.rs new file mode 100644 index 00000000000..4e2e400cec0 --- /dev/null +++ b/src/test/ui/once-move-out-on-heap.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/one-tuple.rs b/src/test/ui/one-tuple.rs new file mode 100644 index 00000000000..00fbadce1ac --- /dev/null +++ b/src/test/ui/one-tuple.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/op-assign-builtins-by-ref.rs b/src/test/ui/op-assign-builtins-by-ref.rs new file mode 100644 index 00000000000..96853854d6c --- /dev/null +++ b/src/test/ui/op-assign-builtins-by-ref.rs @@ -0,0 +1,76 @@ +// 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/src/test/ui/opeq.rs b/src/test/ui/opeq.rs new file mode 100644 index 00000000000..9737be97fa3 --- /dev/null +++ b/src/test/ui/opeq.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/operator-associativity.rs b/src/test/ui/operator-associativity.rs new file mode 100644 index 00000000000..4f40c80bc4c --- /dev/null +++ b/src/test/ui/operator-associativity.rs @@ -0,0 +1,4 @@ +// run-pass +// Testcase for issue #130, operator associativity. + +pub fn main() { assert_eq!(3 * 5 / 2, 7); } diff --git a/src/test/ui/operator-multidispatch.rs b/src/test/ui/operator-multidispatch.rs new file mode 100644 index 00000000000..0d1dcfd8bdd --- /dev/null +++ b/src/test/ui/operator-multidispatch.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/operator-overloading.rs b/src/test/ui/operator-overloading.rs new file mode 100644 index 00000000000..6b3abcbc76c --- /dev/null +++ b/src/test/ui/operator-overloading.rs @@ -0,0 +1,81 @@ +// 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/src/test/ui/optimization-fuel-0.rs b/src/test/ui/optimization-fuel-0.rs new file mode 100644 index 00000000000..f86972b7348 --- /dev/null +++ b/src/test/ui/optimization-fuel-0.rs @@ -0,0 +1,16 @@ +// run-pass + +#![crate_name="foo"] + +use std::mem::size_of; + +// (#55495: The --error-format is to sidestep an issue in our test harness) +// compile-flags: --error-format human -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/src/test/ui/optimization-fuel-0.stderr b/src/test/ui/optimization-fuel-0.stderr new file mode 100644 index 00000000000..3ad405b2b50 --- /dev/null +++ b/src/test/ui/optimization-fuel-0.stderr @@ -0,0 +1 @@ +optimization-fuel-exhausted: Reorder fields of "S1" diff --git a/src/test/ui/optimization-fuel-1.rs b/src/test/ui/optimization-fuel-1.rs new file mode 100644 index 00000000000..98283066361 --- /dev/null +++ b/src/test/ui/optimization-fuel-1.rs @@ -0,0 +1,17 @@ +// run-pass + +#![crate_name="foo"] + +use std::mem::size_of; + +// (#55495: The --error-format is to sidestep an issue in our test harness) +// compile-flags: --error-format human -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/src/test/ui/optimization-fuel-1.stderr b/src/test/ui/optimization-fuel-1.stderr new file mode 100644 index 00000000000..197e45219c3 --- /dev/null +++ b/src/test/ui/optimization-fuel-1.stderr @@ -0,0 +1 @@ +optimization-fuel-exhausted: Reorder fields of "S2" diff --git a/src/test/ui/option-ext.rs b/src/test/ui/option-ext.rs new file mode 100644 index 00000000000..76d0cf43984 --- /dev/null +++ b/src/test/ui/option-ext.rs @@ -0,0 +1,10 @@ +// run-pass + +pub fn main() { + let thing = "{{ f }}"; + let f = thing.find("{{"); + + if f.is_none() { + println!("None!"); + } +} diff --git a/src/test/ui/option-unwrap.rs b/src/test/ui/option-unwrap.rs new file mode 100644 index 00000000000..173f803ee24 --- /dev/null +++ b/src/test/ui/option-unwrap.rs @@ -0,0 +1,32 @@ +// run-pass + +#![allow(non_camel_case_types)] +use std::cell::Cell; + +struct dtor<'a> { + x: &'a Cell, +} + +impl<'a> Drop for dtor<'a> { + fn drop(&mut self) { + self.x.set(self.x.get() - 1); + } +} + +fn unwrap(o: Option) -> T { + match o { + Some(v) => v, + None => panic!() + } +} + +pub fn main() { + let x = &Cell::new(1); + + { + let b = Some(dtor { x:x }); + let _c = unwrap(b); + } + + assert_eq!(x.get(), 0); +} diff --git a/src/test/ui/out-of-stack.rs b/src/test/ui/out-of-stack.rs new file mode 100644 index 00000000000..5e9265be4b9 --- /dev/null +++ b/src/test/ui/out-of-stack.rs @@ -0,0 +1,90 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unconditional_recursion)] +// ignore-android: FIXME (#20004) +// ignore-musl +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(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 { 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/src/test/ui/out-pointer-aliasing.rs b/src/test/ui/out-pointer-aliasing.rs new file mode 100644 index 00000000000..b28a0910179 --- /dev/null +++ b/src/test/ui/out-pointer-aliasing.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/output-slot-variants.rs b/src/test/ui/output-slot-variants.rs new file mode 100644 index 00000000000..af4caf75669 --- /dev/null +++ b/src/test/ui/output-slot-variants.rs @@ -0,0 +1,70 @@ +// 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/src/test/ui/over-constrained-vregs.rs b/src/test/ui/over-constrained-vregs.rs new file mode 100644 index 00000000000..cc808147600 --- /dev/null +++ b/src/test/ui/over-constrained-vregs.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/overlap-doesnt-conflict-with-specialization.rs b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs new file mode 100644 index 00000000000..3d4069f368d --- /dev/null +++ b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs @@ -0,0 +1,19 @@ +// run-pass + +#![feature(overlapping_marker_traits)] +#![feature(specialization)] + +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/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs b/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs new file mode 100644 index 00000000000..38331390237 --- /dev/null +++ b/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs b/src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs new file mode 100644 index 00000000000..112455f91f9 --- /dev/null +++ b/src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs @@ -0,0 +1,30 @@ +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/src/test/ui/overloaded/overloaded-autoderef-count.rs b/src/test/ui/overloaded/overloaded-autoderef-count.rs new file mode 100644 index 00000000000..d58deda09f7 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef-count.rs @@ -0,0 +1,74 @@ +// 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/src/test/ui/overloaded/overloaded-autoderef-indexing.rs b/src/test/ui/overloaded/overloaded-autoderef-indexing.rs new file mode 100644 index 00000000000..1c8c7cca93c --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef-indexing.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/overloaded/overloaded-autoderef-order.rs b/src/test/ui/overloaded/overloaded-autoderef-order.rs new file mode 100644 index 00000000000..1ae16d2a7fc --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef-order.rs @@ -0,0 +1,71 @@ +// 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/src/test/ui/overloaded/overloaded-autoderef-vtable.rs b/src/test/ui/overloaded/overloaded-autoderef-vtable.rs new file mode 100644 index 00000000000..f8e6d12088f --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef-vtable.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/overloaded/overloaded-autoderef-xcrate.rs b/src/test/ui/overloaded/overloaded-autoderef-xcrate.rs new file mode 100644 index 00000000000..d065e825cc3 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef-xcrate.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/overloaded/overloaded-autoderef.rs b/src/test/ui/overloaded/overloaded-autoderef.rs new file mode 100644 index 00000000000..e850633e34f --- /dev/null +++ b/src/test/ui/overloaded/overloaded-autoderef.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/overloaded/overloaded-calls-object-one-arg.rs b/src/test/ui/overloaded/overloaded-calls-object-one-arg.rs new file mode 100644 index 00000000000..1afab9a1ffb --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-object-one-arg.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/overloaded/overloaded-calls-object-two-args.rs b/src/test/ui/overloaded/overloaded-calls-object-two-args.rs new file mode 100644 index 00000000000..38087bc8710 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-object-two-args.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/overloaded/overloaded-calls-object-zero-args.rs b/src/test/ui/overloaded/overloaded-calls-object-zero-args.rs new file mode 100644 index 00000000000..9a7bfaa9bf4 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-object-zero-args.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/overloaded/overloaded-calls-param-vtables.rs b/src/test/ui/overloaded/overloaded-calls-param-vtables.rs new file mode 100644 index 00000000000..fde1ad20f7d --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-param-vtables.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/overloaded/overloaded-calls-simple.rs b/src/test/ui/overloaded/overloaded-calls-simple.rs new file mode 100644 index 00000000000..41318360799 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-simple.rs @@ -0,0 +1,78 @@ +// 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/src/test/ui/overloaded/overloaded-calls-zero-args.rs b/src/test/ui/overloaded/overloaded-calls-zero-args.rs new file mode 100644 index 00000000000..69ca88619b8 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-calls-zero-args.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/overloaded/overloaded-deref-count.rs b/src/test/ui/overloaded/overloaded-deref-count.rs new file mode 100644 index 00000000000..e2f1e10b5c8 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-deref-count.rs @@ -0,0 +1,78 @@ +// 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/src/test/ui/overloaded/overloaded-deref.rs b/src/test/ui/overloaded/overloaded-deref.rs new file mode 100644 index 00000000000..73d8232a322 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-deref.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/overloaded/overloaded-index-assoc-list.rs b/src/test/ui/overloaded/overloaded-index-assoc-list.rs new file mode 100644 index 00000000000..eb027afeacd --- /dev/null +++ b/src/test/ui/overloaded/overloaded-index-assoc-list.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/overloaded/overloaded-index-autoderef.rs b/src/test/ui/overloaded/overloaded-index-autoderef.rs new file mode 100644 index 00000000000..6996ee32933 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-index-autoderef.rs @@ -0,0 +1,77 @@ +// 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/src/test/ui/overloaded/overloaded-index-in-field.rs b/src/test/ui/overloaded/overloaded-index-in-field.rs new file mode 100644 index 00000000000..8a1fa7deb99 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-index-in-field.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/overloaded/overloaded-index.rs b/src/test/ui/overloaded/overloaded-index.rs new file mode 100644 index 00000000000..5ad6d2e7004 --- /dev/null +++ b/src/test/ui/overloaded/overloaded-index.rs @@ -0,0 +1,64 @@ +// 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/src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs new file mode 100644 index 00000000000..c87ba6a023b --- /dev/null +++ b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs @@ -0,0 +1,95 @@ +// 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/src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs new file mode 100644 index 00000000000..61edd2ace3a --- /dev/null +++ b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/owned-implies-static.rs b/src/test/ui/owned-implies-static.rs new file mode 100644 index 00000000000..2efa8cc02f4 --- /dev/null +++ b/src/test/ui/owned-implies-static.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_x: T) {} + +pub fn main() { + f(Box::new(5)); +} diff --git a/src/test/ui/packed/auxiliary/packed.rs b/src/test/ui/packed/auxiliary/packed.rs new file mode 100644 index 00000000000..cba166facf4 --- /dev/null +++ b/src/test/ui/packed/auxiliary/packed.rs @@ -0,0 +1,19 @@ +#[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/src/test/ui/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs new file mode 100644 index 00000000000..6ac42ed0d47 --- /dev/null +++ b/src/test/ui/packed/packed-struct-borrow-element.rs @@ -0,0 +1,35 @@ +// run-pass +#![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/src/test/ui/packed/packed-struct-drop-aligned.rs b/src/test/ui/packed/packed-struct-drop-aligned.rs new file mode 100644 index 00000000000..fab3bbedac6 --- /dev/null +++ b/src/test/ui/packed/packed-struct-drop-aligned.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/packed/packed-struct-generic-layout.rs b/src/test/ui/packed/packed-struct-generic-layout.rs new file mode 100644 index 00000000000..e064eede4ce --- /dev/null +++ b/src/test/ui/packed/packed-struct-generic-layout.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/packed/packed-struct-generic-size.rs b/src/test/ui/packed/packed-struct-generic-size.rs new file mode 100644 index 00000000000..7c93e46c30c --- /dev/null +++ b/src/test/ui/packed/packed-struct-generic-size.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/packed/packed-struct-layout.rs b/src/test/ui/packed/packed-struct-layout.rs new file mode 100644 index 00000000000..d49c222e648 --- /dev/null +++ b/src/test/ui/packed/packed-struct-layout.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/packed/packed-struct-match.rs b/src/test/ui/packed/packed-struct-match.rs new file mode 100644 index 00000000000..9a572ced717 --- /dev/null +++ b/src/test/ui/packed/packed-struct-match.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/packed/packed-struct-optimized-enum.rs b/src/test/ui/packed/packed-struct-optimized-enum.rs new file mode 100644 index 00000000000..7ce62464ef0 --- /dev/null +++ b/src/test/ui/packed/packed-struct-optimized-enum.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/packed/packed-struct-size-xc.rs b/src/test/ui/packed/packed-struct-size-xc.rs new file mode 100644 index 00000000000..46112d51d83 --- /dev/null +++ b/src/test/ui/packed/packed-struct-size-xc.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/packed/packed-struct-size.rs b/src/test/ui/packed/packed-struct-size.rs new file mode 100644 index 00000000000..c832c7cfad5 --- /dev/null +++ b/src/test/ui/packed/packed-struct-size.rs @@ -0,0 +1,157 @@ +// 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/src/test/ui/packed/packed-struct-vec.rs b/src/test/ui/packed/packed-struct-vec.rs new file mode 100644 index 00000000000..18676cfc22e --- /dev/null +++ b/src/test/ui/packed/packed-struct-vec.rs @@ -0,0 +1,120 @@ +// 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/src/test/ui/packed/packed-tuple-struct-layout.rs b/src/test/ui/packed/packed-tuple-struct-layout.rs new file mode 100644 index 00000000000..b88637fbe56 --- /dev/null +++ b/src/test/ui/packed/packed-tuple-struct-layout.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/packed/packed-tuple-struct-size.rs b/src/test/ui/packed/packed-tuple-struct-size.rs new file mode 100644 index 00000000000..f7a3c903fca --- /dev/null +++ b/src/test/ui/packed/packed-tuple-struct-size.rs @@ -0,0 +1,79 @@ +// 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/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs b/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs new file mode 100644 index 00000000000..659864c1d9b --- /dev/null +++ b/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs b/src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs new file mode 100644 index 00000000000..9c099911eab --- /dev/null +++ b/src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/panic-runtime/abort.rs b/src/test/ui/panic-runtime/abort.rs new file mode 100644 index 00000000000..f625fe35d72 --- /dev/null +++ b/src/test/ui/panic-runtime/abort.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs b/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs new file mode 100644 index 00000000000..c0e05740542 --- /dev/null +++ b/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/panic-runtime/link-to-abort.rs b/src/test/ui/panic-runtime/link-to-abort.rs new file mode 100644 index 00000000000..422206c574d --- /dev/null +++ b/src/test/ui/panic-runtime/link-to-abort.rs @@ -0,0 +1,11 @@ +// run-pass + +// compile-flags:-C panic=abort +// no-prefer-dynamic +// ignore-macos + +#![feature(panic_abort)] + +extern crate panic_abort; + +fn main() {} diff --git a/src/test/ui/panic-runtime/link-to-unwind.rs b/src/test/ui/panic-runtime/link-to-unwind.rs new file mode 100644 index 00000000000..59036ca99bd --- /dev/null +++ b/src/test/ui/panic-runtime/link-to-unwind.rs @@ -0,0 +1,10 @@ +// run-pass + +// no-prefer-dynamic + +#![feature(panic_unwind)] + +extern crate panic_unwind; + +fn main() { +} diff --git a/src/test/ui/panic-runtime/lto-abort.rs b/src/test/ui/panic-runtime/lto-abort.rs new file mode 100644 index 00000000000..8fff71a629a --- /dev/null +++ b/src/test/ui/panic-runtime/lto-abort.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/panic-runtime/lto-unwind.rs b/src/test/ui/panic-runtime/lto-unwind.rs new file mode 100644 index 00000000000..94a0b596e4a --- /dev/null +++ b/src/test/ui/panic-runtime/lto-unwind.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/panic-uninitialized-zeroed.rs b/src/test/ui/panic-uninitialized-zeroed.rs new file mode 100644 index 00000000000..0c97babd51c --- /dev/null +++ b/src/test/ui/panic-uninitialized-zeroed.rs @@ -0,0 +1,102 @@ +// run-pass +// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding +// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results +// in a runtime panic. + +#![feature(never_type)] +#![allow(deprecated)] + +use std::{mem, panic}; + +#[allow(dead_code)] +struct Foo { + x: u8, + y: !, +} + +enum Bar {} + +fn main() { + unsafe { + assert_eq!( + panic::catch_unwind(|| { + mem::uninitialized::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type !" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::zeroed::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type !" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::MaybeUninit::::uninit().assume_init() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type !" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::uninitialized::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Foo" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::zeroed::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Foo" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::MaybeUninit::::uninit().assume_init() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Foo" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::uninitialized::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Bar" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::zeroed::() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Bar" + })), + Some(true) + ); + + assert_eq!( + panic::catch_unwind(|| { + mem::MaybeUninit::::uninit().assume_init() + }).err().and_then(|a| a.downcast_ref::().map(|s| { + s == "Attempted to instantiate uninhabited type Bar" + })), + Some(true) + ); + } +} diff --git a/src/test/ui/panics/panic-handler-chain.rs b/src/test/ui/panics/panic-handler-chain.rs new file mode 100644 index 00000000000..93044b5cb25 --- /dev/null +++ b/src/test/ui/panics/panic-handler-chain.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/panics/panic-handler-flail-wildly.rs b/src/test/ui/panics/panic-handler-flail-wildly.rs new file mode 100644 index 00000000000..6badd203842 --- /dev/null +++ b/src/test/ui/panics/panic-handler-flail-wildly.rs @@ -0,0 +1,55 @@ +// 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/src/test/ui/panics/panic-handler-set-twice.rs b/src/test/ui/panics/panic-handler-set-twice.rs new file mode 100644 index 00000000000..0312ed221ca --- /dev/null +++ b/src/test/ui/panics/panic-handler-set-twice.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/panics/panic-in-dtor-drops-fields.rs b/src/test/ui/panics/panic-in-dtor-drops-fields.rs new file mode 100644 index 00000000000..caddd942dc0 --- /dev/null +++ b/src/test/ui/panics/panic-in-dtor-drops-fields.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/panics/panic-recover-propagate.rs b/src/test/ui/panics/panic-recover-propagate.rs new file mode 100644 index 00000000000..7969336ca74 --- /dev/null +++ b/src/test/ui/panics/panic-recover-propagate.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/panics/panic-safe.rs b/src/test/ui/panics/panic-safe.rs new file mode 100644 index 00000000000..9867cc56406 --- /dev/null +++ b/src/test/ui/panics/panic-safe.rs @@ -0,0 +1,51 @@ +// run-pass +#![allow(dead_code)] + +use std::panic::{UnwindSafe, AssertUnwindSafe}; +use std::cell::RefCell; +use std::sync::{Mutex, RwLock, Arc}; +use std::rc::Rc; + +struct Foo { a: i32 } + +fn assert() {} + +fn main() { + assert::(); + assert::<&i32>(); + assert::<*mut i32>(); + assert::<*const i32>(); + assert::(); + assert::(); + assert::<&str>(); + assert::(); + assert::<&Foo>(); + assert::>(); + assert::(); + assert::>(); + assert::>(); + assert::>(); + assert::>(); + assert::<&Mutex>(); + assert::<&RwLock>(); + assert::>(); + assert::>(); + assert::>(); + + trait Trait: UnwindSafe {} + assert::>(); + + fn bar() { + assert::>(); + assert::>(); + } + fn baz() { + assert::>(); + assert::>(); + assert::>(); + assert::>(); + assert::<&AssertUnwindSafe>(); + assert::>>(); + assert::>>(); + } +} diff --git a/src/test/ui/paren-free.rs b/src/test/ui/paren-free.rs new file mode 100644 index 00000000000..8e8bb8800ec --- /dev/null +++ b/src/test/ui/paren-free.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/parse-assoc-type-lt.rs b/src/test/ui/parse-assoc-type-lt.rs new file mode 100644 index 00000000000..d3fe6079a5d --- /dev/null +++ b/src/test/ui/parse-assoc-type-lt.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + type T; + fn foo() -> Box<::T>; +} + +fn main() {} diff --git a/src/test/ui/parse-panic.rs b/src/test/ui/parse-panic.rs new file mode 100644 index 00000000000..aeb2ba4faa5 --- /dev/null +++ b/src/test/ui/parse-panic.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unreachable_code)] + +fn dont_call_me() { panic!(); println!("{}", 1); } + +pub fn main() { } diff --git a/src/test/ui/parser-unicode-whitespace.rs b/src/test/ui/parser-unicode-whitespace.rs new file mode 100644 index 00000000000..2d1fa7dc42e --- /dev/null +++ b/src/test/ui/parser-unicode-whitespace.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/path.rs b/src/test/ui/path.rs new file mode 100644 index 00000000000..4c137de82d0 --- /dev/null +++ b/src/test/ui/path.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod foo { + pub fn bar(_offset: usize) { } +} + +pub fn main() { foo::bar(0); } diff --git a/src/test/ui/paths-containing-nul.rs b/src/test/ui/paths-containing-nul.rs new file mode 100644 index 00000000000..c9bf710b8e7 --- /dev/null +++ b/src/test/ui/paths-containing-nul.rs @@ -0,0 +1,50 @@ +// 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(|_| ())) +} + +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/src/test/ui/print-stdout-eprint-stderr.rs b/src/test/ui/print-stdout-eprint-stderr.rs new file mode 100644 index 00000000000..70c083e0800 --- /dev/null +++ b/src/test/ui/print-stdout-eprint-stderr.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs b/src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs new file mode 100644 index 00000000000..8ccbd3f12bf --- /dev/null +++ b/src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs @@ -0,0 +1,9 @@ +pub trait A { + fn frob(&self); +} + +impl A for isize { fn frob(&self) {} } + +pub fn frob(t: T) { + t.frob(); +} diff --git a/src/test/ui/privacy/auxiliary/privacy_reexport.rs b/src/test/ui/privacy/auxiliary/privacy_reexport.rs new file mode 100644 index 00000000000..6b72dbc9233 --- /dev/null +++ b/src/test/ui/privacy/auxiliary/privacy_reexport.rs @@ -0,0 +1,6 @@ +pub extern crate core; +pub use foo as bar; + +pub mod foo { + pub fn frob() {} +} diff --git a/src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs b/src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs new file mode 100644 index 00000000000..74d3504d5be --- /dev/null +++ b/src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs @@ -0,0 +1,10 @@ +pub mod a { + pub use a::b::c; + + pub mod b { + pub mod c { + fn f(){} + fn g(){} + } + } +} diff --git a/src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs b/src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs new file mode 100644 index 00000000000..772c9627a71 --- /dev/null +++ b/src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs @@ -0,0 +1,3 @@ +pub struct Foo { + pub name: isize +} diff --git a/src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs b/src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs new file mode 100644 index 00000000000..20d7066d36d --- /dev/null +++ b/src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs @@ -0,0 +1,3 @@ +extern crate pub_use_xcrate1; + +pub use pub_use_xcrate1::Foo; diff --git a/src/test/ui/privacy/priv-impl-prim-ty.rs b/src/test/ui/privacy/priv-impl-prim-ty.rs new file mode 100644 index 00000000000..5d6a6b64ed3 --- /dev/null +++ b/src/test/ui/privacy/priv-impl-prim-ty.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/privacy/privacy-ns.rs b/src/test/ui/privacy/privacy-ns.rs new file mode 100644 index 00000000000..c32e3f17880 --- /dev/null +++ b/src/test/ui/privacy/privacy-ns.rs @@ -0,0 +1,114 @@ +// 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/src/test/ui/privacy/privacy-reexport.rs b/src/test/ui/privacy/privacy-reexport.rs new file mode 100644 index 00000000000..b3ec3af04ac --- /dev/null +++ b/src/test/ui/privacy/privacy-reexport.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/privacy/private-class-field.rs b/src/test/ui/privacy/private-class-field.rs new file mode 100644 index 00000000000..98e32ee0745 --- /dev/null +++ b/src/test/ui/privacy/private-class-field.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/privacy/pub-extern-privacy.rs b/src/test/ui/privacy/pub-extern-privacy.rs new file mode 100644 index 00000000000..832acfbadcb --- /dev/null +++ b/src/test/ui/privacy/pub-extern-privacy.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/privacy/pub-use-xcrate.rs b/src/test/ui/privacy/pub-use-xcrate.rs new file mode 100644 index 00000000000..e8a6e8cf182 --- /dev/null +++ b/src/test/ui/privacy/pub-use-xcrate.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/privacy/pub_use_mods_xcrate_exe.rs b/src/test/ui/privacy/pub_use_mods_xcrate_exe.rs new file mode 100644 index 00000000000..f163619e7cb --- /dev/null +++ b/src/test/ui/privacy/pub_use_mods_xcrate_exe.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/proc-macro/add-impl.rs b/src/test/ui/proc-macro/add-impl.rs new file mode 100644 index 00000000000..ff2897a5e86 --- /dev/null +++ b/src/test/ui/proc-macro/add-impl.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/proc-macro/append-impl.rs b/src/test/ui/proc-macro/append-impl.rs new file mode 100644 index 00000000000..a4938401348 --- /dev/null +++ b/src/test/ui/proc-macro/append-impl.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/proc-macro/attr-args.rs b/src/test/ui/proc-macro/attr-args.rs new file mode 100644 index 00000000000..764f507abfc --- /dev/null +++ b/src/test/ui/proc-macro/attr-args.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/proc-macro/attr-cfg.rs b/src/test/ui/proc-macro/attr-cfg.rs new file mode 100644 index 00000000000..2aed9e2e814 --- /dev/null +++ b/src/test/ui/proc-macro/attr-cfg.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/proc-macro/attr-on-trait.rs b/src/test/ui/proc-macro/attr-on-trait.rs new file mode 100644 index 00000000000..e0edee630a4 --- /dev/null +++ b/src/test/ui/proc-macro/attr-on-trait.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/proc-macro/auxiliary/add-impl.rs b/src/test/ui/proc-macro/auxiliary/add-impl.rs new file mode 100644 index 00000000000..741e64875b6 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/add-impl.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/proc-macro/auxiliary/append-impl.rs b/src/test/ui/proc-macro/auxiliary/append-impl.rs new file mode 100644 index 00000000000..b032b133759 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/append-impl.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(Append)] +pub fn derive_a(input: TokenStream) -> TokenStream { + "impl Append for A { + fn foo(&self) {} + } + ".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/attr-args.rs b/src/test/ui/proc-macro/auxiliary/attr-args.rs new file mode 100644 index 00000000000..8dd2a5ac786 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/attr-args.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/proc-macro/auxiliary/attr-cfg.rs b/src/test/ui/proc-macro/auxiliary/attr-cfg.rs new file mode 100644 index 00000000000..f50e18d7be3 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/attr-cfg.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/proc-macro/auxiliary/attr-on-trait.rs b/src/test/ui/proc-macro/auxiliary/attr-on-trait.rs new file mode 100644 index 00000000000..d89aaac59f6 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/attr-on-trait.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/proc-macro/auxiliary/bang-macro.rs b/src/test/ui/proc-macro/auxiliary/bang-macro.rs new file mode 100644 index 00000000000..ff000228218 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/bang-macro.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/proc-macro/auxiliary/call-site.rs b/src/test/ui/proc-macro/auxiliary/call-site.rs new file mode 100644 index 00000000000..e64a5a3438a --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/call-site.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 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/src/test/ui/proc-macro/auxiliary/count_compound_ops.rs b/src/test/ui/proc-macro/auxiliary/count_compound_ops.rs new file mode 100644 index 00000000000..e09622e48bf --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/count_compound_ops.rs @@ -0,0 +1,32 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_hygiene, 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/src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs new file mode 100644 index 00000000000..41f73f5963a --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.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(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/src/test/ui/proc-macro/auxiliary/derive-a.rs b/src/test/ui/proc-macro/auxiliary/derive-a.rs new file mode 100644 index 00000000000..cd2be5fd84d --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-a.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(A)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("struct A;")); + "".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/derive-atob.rs b/src/test/ui/proc-macro/auxiliary/derive-atob.rs new file mode 100644 index 00000000000..e78e5bb8f4c --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-atob.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(AToB)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct A;"); + "struct B;".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/ui/proc-macro/auxiliary/derive-attr-cfg.rs new file mode 100644 index 00000000000..e7e9634e0bd --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-attr-cfg.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(Foo, attributes(foo))] +pub fn derive(input: TokenStream) -> TokenStream { + assert!(!input.to_string().contains("#[cfg(any())]")); + "".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs b/src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs new file mode 100644 index 00000000000..3e6af67a9f4 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-b-rpass.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(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/src/test/ui/proc-macro/auxiliary/derive-ctod.rs b/src/test/ui/proc-macro/auxiliary/derive-ctod.rs new file mode 100644 index 00000000000..dbf44ed1b05 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-ctod.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(CToD)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct C;"); + "struct D;".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/derive-nothing.rs b/src/test/ui/proc-macro/auxiliary/derive-nothing.rs new file mode 100644 index 00000000000..b6d1e133af7 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-nothing.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(Nothing)] +pub fn nothing(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/derive-same-struct.rs b/src/test/ui/proc-macro/auxiliary/derive-same-struct.rs new file mode 100644 index 00000000000..ce7a50d2381 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-same-struct.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs b/src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs new file mode 100644 index 00000000000..a6f0eec126a --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/proc-macro/auxiliary/derive-union.rs b/src/test/ui/proc-macro/auxiliary/derive-union.rs new file mode 100644 index 00000000000..d950e1e773c --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-union.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(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/src/test/ui/proc-macro/auxiliary/double.rs b/src/test/ui/proc-macro/auxiliary/double.rs new file mode 100644 index 00000000000..3a2e8d04c36 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/double.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +// 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 { + format!("mod foo {{ {} }}", input.to_string()).parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/empty-crate.rs b/src/test/ui/proc-macro/auxiliary/empty-crate.rs new file mode 100644 index 00000000000..1cf7534b289 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/empty-crate.rs @@ -0,0 +1,5 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(unused_variables)] diff --git a/src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs new file mode 100644 index 00000000000..5155a4b8558 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/proc-macro/auxiliary/external-crate-var.rs b/src/test/ui/proc-macro/auxiliary/external-crate-var.rs new file mode 100644 index 00000000000..4319e921225 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/external-crate-var.rs @@ -0,0 +1,40 @@ +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/src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs new file mode 100644 index 00000000000..d1a1c584f8b --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/proc-macro/auxiliary/hygiene_example.rs b/src/test/ui/proc-macro/auxiliary/hygiene_example.rs new file mode 100644 index 00000000000..f7e7e0b5751 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/hygiene_example.rs @@ -0,0 +1,7 @@ +extern crate hygiene_example_codegen; + +pub use hygiene_example_codegen::hello; + +pub fn print(string: &str) { + println!("{}", string); +} diff --git a/src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs new file mode 100644 index 00000000000..5e50a6e916f --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs @@ -0,0 +1,27 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote, proc_macro_hygiene)] +#![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/src/test/ui/proc-macro/auxiliary/issue-39889.rs b/src/test/ui/proc-macro/auxiliary/issue-39889.rs new file mode 100644 index 00000000000..e7af66da797 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-39889.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(Issue39889)] +pub fn f(_input: TokenStream) -> TokenStream { + let rules = r#" + macro_rules! id { + ($($tt:tt)*) => { $($tt)* }; + } + "#; + rules.parse().unwrap() +} diff --git a/src/test/ui/proc-macro/auxiliary/issue-42708.rs b/src/test/ui/proc-macro/auxiliary/issue-42708.rs new file mode 100644 index 00000000000..dae05204b8b --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-42708.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(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/src/test/ui/proc-macro/auxiliary/issue-50061.rs b/src/test/ui/proc-macro/auxiliary/issue-50061.rs new file mode 100644 index 00000000000..f5fe8cabbce --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-50061.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 check(_a: TokenStream, b: TokenStream) -> TokenStream { + b.into_iter().collect() +} diff --git a/src/test/ui/proc-macro/auxiliary/modify-ast.rs b/src/test/ui/proc-macro/auxiliary/modify-ast.rs new file mode 100644 index 00000000000..cc582c1522c --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/modify-ast.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/proc-macro/auxiliary/negative-token.rs b/src/test/ui/proc-macro/auxiliary/negative-token.rs new file mode 100644 index 00000000000..8b89f2e3731 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/negative-token.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/proc-macro/auxiliary/not-joint.rs b/src/test/ui/proc-macro/auxiliary/not-joint.rs new file mode 100644 index 00000000000..e6c09f7628e --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/not-joint.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/proc-macro/auxiliary/span-api-tests.rs b/src/test/ui/proc-macro/auxiliary/span-api-tests.rs new file mode 100644 index 00000000000..ad1e770a4dc --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/span-api-tests.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/proc-macro/auxiliary/span-test-macros.rs b/src/test/ui/proc-macro/auxiliary/span-test-macros.rs new file mode 100644 index 00000000000..9a78f0a8955 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/span-test-macros.rs @@ -0,0 +1,9 @@ +#[macro_export] +macro_rules! reemit_legacy { + ($($tok:tt)*) => ($($tok)*) +} + +#[macro_export] +macro_rules! say_hello_extern { + ($macname:ident) => ( $macname! { "Hello, world!" }) +} diff --git a/src/test/ui/proc-macro/bang-macro.rs b/src/test/ui/proc-macro/bang-macro.rs new file mode 100644 index 00000000000..7073c71538c --- /dev/null +++ b/src/test/ui/proc-macro/bang-macro.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:bang-macro.rs + +#![feature(proc_macro_hygiene)] + +extern crate bang_macro; +use bang_macro::rewrite; + +fn main() { + assert_eq!(rewrite!("Hello, world!"), "NOT Hello, world!"); +} diff --git a/src/test/ui/proc-macro/call-site.rs b/src/test/ui/proc-macro/call-site.rs new file mode 100644 index 00000000000..096d0ec533a --- /dev/null +++ b/src/test/ui/proc-macro/call-site.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(unused_variables)] +#![allow(unused_imports)] +// aux-build:call-site.rs + +#![feature(proc_macro_hygiene)] + +extern crate call_site; +use call_site::*; + +fn main() { + let x1 = 10; + call_site::check!(let x2 = x1;); + let x6 = x5; +} diff --git a/src/test/ui/proc-macro/count_compound_ops.rs b/src/test/ui/proc-macro/count_compound_ops.rs new file mode 100644 index 00000000000..966ab616cdf --- /dev/null +++ b/src/test/ui/proc-macro/count_compound_ops.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:count_compound_ops.rs + +#![feature(proc_macro_hygiene)] + +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/src/test/ui/proc-macro/custom-attr-only-one-derive.rs b/src/test/ui/proc-macro/custom-attr-only-one-derive.rs new file mode 100644 index 00000000000..2cd5b487301 --- /dev/null +++ b/src/test/ui/proc-macro/custom-attr-only-one-derive.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/proc-macro/derive-attr-cfg.rs b/src/test/ui/proc-macro/derive-attr-cfg.rs new file mode 100644 index 00000000000..3947746286d --- /dev/null +++ b/src/test/ui/proc-macro/derive-attr-cfg.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/proc-macro/derive-b.rs b/src/test/ui/proc-macro/derive-b.rs new file mode 100644 index 00000000000..a026c2bd77a --- /dev/null +++ b/src/test/ui/proc-macro/derive-b.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/proc-macro/derive-same-struct.rs b/src/test/ui/proc-macro/derive-same-struct.rs new file mode 100644 index 00000000000..528b0f22a81 --- /dev/null +++ b/src/test/ui/proc-macro/derive-same-struct.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/proc-macro/derive-same-struct.stdout b/src/test/ui/proc-macro/derive-same-struct.stdout new file mode 100644 index 00000000000..77605de5e33 --- /dev/null +++ b/src/test/ui/proc-macro/derive-same-struct.stdout @@ -0,0 +1 @@ +input1: "struct A;" diff --git a/src/test/ui/proc-macro/derive-test.rs b/src/test/ui/proc-macro/derive-test.rs new file mode 100644 index 00000000000..b81e38432e8 --- /dev/null +++ b/src/test/ui/proc-macro/derive-test.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/proc-macro/derive-two-attrs.rs b/src/test/ui/proc-macro/derive-two-attrs.rs new file mode 100644 index 00000000000..08225b8e3f2 --- /dev/null +++ b/src/test/ui/proc-macro/derive-two-attrs.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/proc-macro/derive-union.rs b/src/test/ui/proc-macro/derive-union.rs new file mode 100644 index 00000000000..e83eee0936a --- /dev/null +++ b/src/test/ui/proc-macro/derive-union.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/proc-macro/empty-crate.rs b/src/test/ui/proc-macro/empty-crate.rs new file mode 100644 index 00000000000..3e54c9feebc --- /dev/null +++ b/src/test/ui/proc-macro/empty-crate.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(unused_imports)] +// aux-build:empty-crate.rs + +#[macro_use] +extern crate empty_crate; + +fn main() {} diff --git a/src/test/ui/proc-macro/expand-with-a-macro.rs b/src/test/ui/proc-macro/expand-with-a-macro.rs new file mode 100644 index 00000000000..418178d0f0e --- /dev/null +++ b/src/test/ui/proc-macro/expand-with-a-macro.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/proc-macro/gen-lifetime-token.rs b/src/test/ui/proc-macro/gen-lifetime-token.rs new file mode 100644 index 00000000000..588bd2b76c1 --- /dev/null +++ b/src/test/ui/proc-macro/gen-lifetime-token.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/proc-macro/hygiene_example.rs b/src/test/ui/proc-macro/hygiene_example.rs new file mode 100644 index 00000000000..56ea9daacc3 --- /dev/null +++ b/src/test/ui/proc-macro/hygiene_example.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(unused_macros)] +// aux-build:hygiene_example_codegen.rs +// aux-build:hygiene_example.rs + +#![feature(proc_macro_hygiene)] + +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/src/test/ui/proc-macro/issue-39889.rs b/src/test/ui/proc-macro/issue-39889.rs new file mode 100644 index 00000000000..ada125a215a --- /dev/null +++ b/src/test/ui/proc-macro/issue-39889.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/proc-macro/issue-42708.rs b/src/test/ui/proc-macro/issue-42708.rs new file mode 100644 index 00000000000..e8f445aaaf7 --- /dev/null +++ b/src/test/ui/proc-macro/issue-42708.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/proc-macro/issue-50061.rs b/src/test/ui/proc-macro/issue-50061.rs new file mode 100644 index 00000000000..01c6b80b46c --- /dev/null +++ b/src/test/ui/proc-macro/issue-50061.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/proc-macro/load-two.rs b/src/test/ui/proc-macro/load-two.rs new file mode 100644 index 00000000000..5ce0e65452e --- /dev/null +++ b/src/test/ui/proc-macro/load-two.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/proc-macro/modify-ast.rs b/src/test/ui/proc-macro/modify-ast.rs new file mode 100644 index 00000000000..ea9bf837c24 --- /dev/null +++ b/src/test/ui/proc-macro/modify-ast.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/proc-macro/negative-token.rs b/src/test/ui/proc-macro/negative-token.rs new file mode 100644 index 00000000000..3d018fe60a1 --- /dev/null +++ b/src/test/ui/proc-macro/negative-token.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:negative-token.rs + +#![feature(proc_macro_hygiene)] + +extern crate negative_token; + +use negative_token::*; + +fn main() { + assert_eq!(-1, neg_one!()); + assert_eq!(-1.0, neg_one_float!()); +} diff --git a/src/test/ui/proc-macro/not-joint.rs b/src/test/ui/proc-macro/not-joint.rs new file mode 100644 index 00000000000..30da2811ed4 --- /dev/null +++ b/src/test/ui/proc-macro/not-joint.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/proc-macro/smoke.rs b/src/test/ui/proc-macro/smoke.rs new file mode 100644 index 00000000000..04625559b91 --- /dev/null +++ b/src/test/ui/proc-macro/smoke.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/proc-macro/span-api-tests.rs b/src/test/ui/proc-macro/span-api-tests.rs new file mode 100644 index 00000000000..3667e14c9e0 --- /dev/null +++ b/src/test/ui/proc-macro/span-api-tests.rs @@ -0,0 +1,62 @@ +// run-pass +// aux-build:span-api-tests.rs +// aux-build:span-test-macros.rs + +// ignore-pretty + +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate span_test_macros; + +extern crate span_api_tests; + +use span_api_tests::{reemit, assert_fake_source_file, 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_fake_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/src/test/ui/proc-macro/struct-field-macro.rs b/src/test/ui/proc-macro/struct-field-macro.rs new file mode 100644 index 00000000000..460f4d9f726 --- /dev/null +++ b/src/test/ui/proc-macro/struct-field-macro.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/proc_macro.rs b/src/test/ui/proc_macro.rs new file mode 100644 index 00000000000..7ff94649003 --- /dev/null +++ b/src/test/ui/proc_macro.rs @@ -0,0 +1,39 @@ +// run-pass +// aux-build:proc_macro_def.rs +// ignore-cross-compile + +#![feature(proc_macro_hygiene)] + +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/src/test/ui/process/process-envs.rs b/src/test/ui/process/process-envs.rs new file mode 100644 index 00000000000..a7779c55f1f --- /dev/null +++ b/src/test/ui/process/process-envs.rs @@ -0,0 +1,53 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +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/src/test/ui/process/process-exit.rs b/src/test/ui/process/process-exit.rs new file mode 100644 index 00000000000..da3b4ca85c2 --- /dev/null +++ b/src/test/ui/process/process-exit.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/process/process-remove-from-env.rs b/src/test/ui/process/process-remove-from-env.rs new file mode 100644 index 00000000000..32cbb6ac85a --- /dev/null +++ b/src/test/ui/process/process-remove-from-env.rs @@ -0,0 +1,47 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +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/src/test/ui/process/process-sigpipe.rs b/src/test/ui/process/process-sigpipe.rs new file mode 100644 index 00000000000..bf589096006 --- /dev/null +++ b/src/test/ui/process/process-sigpipe.rs @@ -0,0 +1,36 @@ +// 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 + +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/src/test/ui/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs new file mode 100644 index 00000000000..182cf1748fe --- /dev/null +++ b/src/test/ui/process/process-spawn-nonexistent.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/process/process-spawn-with-unicode-params.rs b/src/test/ui/process/process-spawn-with-unicode-params.rs new file mode 100644 index 00000000000..edd3cb26ec3 --- /dev/null +++ b/src/test/ui/process/process-spawn-with-unicode-params.rs @@ -0,0 +1,77 @@ +// 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/src/test/ui/process/process-status-inherits-stdin.rs b/src/test/ui/process/process-status-inherits-stdin.rs new file mode 100644 index 00000000000..f9b2da7e401 --- /dev/null +++ b/src/test/ui/process/process-status-inherits-stdin.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/project-cache-issue-31849.rs b/src/test/ui/project-cache-issue-31849.rs new file mode 100644 index 00000000000..07fb6abaeac --- /dev/null +++ b/src/test/ui/project-cache-issue-31849.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/project-cache-issue-37154.rs b/src/test/ui/project-cache-issue-37154.rs new file mode 100644 index 00000000000..b10239c22d1 --- /dev/null +++ b/src/test/ui/project-cache-issue-37154.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/project-defer-unification.rs b/src/test/ui/project-defer-unification.rs new file mode 100644 index 00000000000..547ff45c229 --- /dev/null +++ b/src/test/ui/project-defer-unification.rs @@ -0,0 +1,104 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unreachable_code)] +// A regression test extracted from image-0.3.11. The point of +// failure was in `index_colors` below. + +use std::ops::{Deref, DerefMut}; + +#[derive(Copy, Clone)] +pub struct Luma { pub data: [T; 1] } + +impl Pixel for Luma { + type Subpixel = T; +} + +pub struct ImageBuffer { + pixels: P, + c: Container, +} + +pub trait GenericImage: Sized { + type Pixel: Pixel; +} + +pub trait Pixel: Copy + Clone { + type Subpixel: Primitive; +} + +pub trait Primitive: Copy + PartialOrd + Clone { +} + +impl GenericImage for ImageBuffer +where P: Pixel + 'static, + Container: Deref + DerefMut, + P::Subpixel: 'static { + + type Pixel = P; +} + +impl Primitive for u8 { } + +impl ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref +{ + pub fn pixels<'a>(&'a self) -> Pixels<'a, Self> { + loop { } + } + + pub fn pixels_mut(&mut self) -> PixelsMut

{ + loop { } + } +} + +pub struct Pixels<'a, I: 'a> { + image: &'a I, + x: u32, + y: u32, + width: u32, + height: u32 +} + +impl<'a, I: GenericImage> Iterator for Pixels<'a, I> { + type Item = (u32, u32, I::Pixel); + + fn next(&mut self) -> Option<(u32, u32, I::Pixel)> { + loop { } + } +} + +pub struct PixelsMut<'a, P: Pixel + 'a> where P::Subpixel: 'a { + chunks: &'a mut P::Subpixel +} + +impl<'a, P: Pixel + 'a> Iterator for PixelsMut<'a, P> where P::Subpixel: 'a { + type Item = &'a mut P; + + fn next(&mut self) -> Option<&'a mut P> { + loop { } + } +} + +pub fn index_colors(image: &ImageBuffer>) + -> ImageBuffer, Vec> +where Pix: Pixel + 'static, +{ + // When NLL-enabled, `let mut` below is deemed unnecessary (due to + // the remaining code being unreachable); so ignore that lint. + #![allow(unused_mut)] + + let mut indices: ImageBuffer<_,Vec<_>> = loop { }; + for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) { + // failured occurred here ^^ because we were requiring that we + // could project Pixel or Subpixel from `T_indices` (type of + // `indices`), but the type is insufficiently constrained + // until we reach the return below. + } + indices +} + +fn main() { } diff --git a/src/test/ui/pure-sum.rs b/src/test/ui/pure-sum.rs new file mode 100644 index 00000000000..2ff6f935a03 --- /dev/null +++ b/src/test/ui/pure-sum.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/purity-infer.rs b/src/test/ui/purity-infer.rs new file mode 100644 index 00000000000..dc0eb89bfa2 --- /dev/null +++ b/src/test/ui/purity-infer.rs @@ -0,0 +1,6 @@ +// run-pass + +fn something(f: F) where F: FnOnce() { f(); } +pub fn main() { + something(|| println!("hi!") ); +} diff --git a/src/test/ui/range-type-infer.rs b/src/test/ui/range-type-infer.rs new file mode 100644 index 00000000000..f07c041717f --- /dev/null +++ b/src/test/ui/range-type-infer.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/range.rs b/src/test/ui/range.rs new file mode 100644 index 00000000000..82983e37ea1 --- /dev/null +++ b/src/test/ui/range.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(unused_comparisons)] +#![allow(dead_code)] +#![allow(unused_mut)] +// Test range syntax. + + +fn foo() -> isize { 42 } + +// Test that range syntax works in return statements +fn return_range_to() -> ::std::ops::RangeTo { return ..1; } +fn return_full_range() -> ::std::ops::RangeFull { return ..; } + +pub fn main() { + let mut count = 0; + for i in 0_usize..10 { + assert!(i >= 0 && i < 10); + count += i; + } + assert_eq!(count, 45); + + let mut count = 0; + let mut range = 0_usize..10; + for i in range { + assert!(i >= 0 && i < 10); + count += i; + } + assert_eq!(count, 45); + + let mut count = 0; + let mut rf = 3_usize..; + for i in rf.take(10) { + assert!(i >= 3 && i < 13); + count += i; + } + assert_eq!(count, 75); + + 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; + } +} diff --git a/src/test/ui/range_inclusive.rs b/src/test/ui/range_inclusive.rs new file mode 100644 index 00000000000..68d9bf7d26b --- /dev/null +++ b/src/test/ui/range_inclusive.rs @@ -0,0 +1,122 @@ +// run-pass +// Test inclusive range syntax. + +#![feature(range_is_empty)] +#![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/src/test/ui/range_inclusive_gate.rs b/src/test/ui/range_inclusive_gate.rs new file mode 100644 index 00000000000..e26e31b44a0 --- /dev/null +++ b/src/test/ui/range_inclusive_gate.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/ranges-precedence.rs b/src/test/ui/ranges-precedence.rs new file mode 100644 index 00000000000..db241ed0ccd --- /dev/null +++ b/src/test/ui/ranges-precedence.rs @@ -0,0 +1,52 @@ +// 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/src/test/ui/raw-fat-ptr.rs b/src/test/ui/raw-fat-ptr.rs new file mode 100644 index 00000000000..9f50659ed60 --- /dev/null +++ b/src/test/ui/raw-fat-ptr.rs @@ -0,0 +1,118 @@ +// 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/src/test/ui/raw-str.rs b/src/test/ui/raw-str.rs new file mode 100644 index 00000000000..0916dddbb7b Binary files /dev/null and b/src/test/ui/raw-str.rs differ diff --git a/src/test/ui/rcvr-borrowed-to-region.rs b/src/test/ui/rcvr-borrowed-to-region.rs new file mode 100644 index 00000000000..37113bc0a05 --- /dev/null +++ b/src/test/ui/rcvr-borrowed-to-region.rs @@ -0,0 +1,29 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait get { + fn get(self) -> 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/src/test/ui/reachable-unnameable-items.rs b/src/test/ui/reachable-unnameable-items.rs new file mode 100644 index 00000000000..f1e53a0d8b4 --- /dev/null +++ b/src/test/ui/reachable-unnameable-items.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/reachable-unnameable-type-alias.rs b/src/test/ui/reachable-unnameable-type-alias.rs new file mode 100644 index 00000000000..461355f87cf --- /dev/null +++ b/src/test/ui/reachable-unnameable-type-alias.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/readalias.rs b/src/test/ui/readalias.rs new file mode 100644 index 00000000000..a6bf61803cf --- /dev/null +++ b/src/test/ui/readalias.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/realloc-16687.rs b/src/test/ui/realloc-16687.rs new file mode 100644 index 00000000000..69292d241c3 --- /dev/null +++ b/src/test/ui/realloc-16687.rs @@ -0,0 +1,183 @@ +// 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)] + +use std::alloc::{Global, Alloc, Layout, handle_alloc_error}; +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 ret = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + + if PRINT { + println!("allocate({:?}) = {:?}", layout, ret); + } + + ret.cast().as_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 ret = Global.realloc(NonNull::new_unchecked(ptr), old, new.size()) + .unwrap_or_else(|_| handle_alloc_error( + Layout::from_size_align_unchecked(new.size(), old.align()) + )); + + if PRINT { + println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", + ptr, old, new, ret); + } + ret.cast().as_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/src/test/ui/reexport-should-still-link.rs b/src/test/ui/reexport-should-still-link.rs new file mode 100644 index 00000000000..913da56a184 --- /dev/null +++ b/src/test/ui/reexport-should-still-link.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/reexport-star.rs b/src/test/ui/reexport-star.rs new file mode 100644 index 00000000000..639ab1a0f3a --- /dev/null +++ b/src/test/ui/reexport-star.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/reexport-test-harness-main.rs b/src/test/ui/reexport-test-harness-main.rs new file mode 100644 index 00000000000..2582975e219 --- /dev/null +++ b/src/test/ui/reexport-test-harness-main.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/refer-to-other-statics-by-value.rs b/src/test/ui/refer-to-other-statics-by-value.rs new file mode 100644 index 00000000000..90f1980f858 --- /dev/null +++ b/src/test/ui/refer-to-other-statics-by-value.rs @@ -0,0 +1,8 @@ +// run-pass + +static A: usize = 42; +static B: usize = A; + +fn main() { + assert_eq!(B, 42); +} diff --git a/src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs b/src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs new file mode 100644 index 00000000000..4221ebfdffb --- /dev/null +++ b/src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/regions/regions-addr-of-ret.rs b/src/test/ui/regions/regions-addr-of-ret.rs new file mode 100644 index 00000000000..e5dcd6db033 --- /dev/null +++ b/src/test/ui/regions/regions-addr-of-ret.rs @@ -0,0 +1,9 @@ +// run-pass +fn f(x: &isize) -> &isize { + return &*x; +} + +pub fn main() { + let three = &3; + println!("{}", *f(three)); +} diff --git a/src/test/ui/regions/regions-assoc-type-region-bound.rs b/src/test/ui/regions/regions-assoc-type-region-bound.rs new file mode 100644 index 00000000000..cbb7d1726d9 --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-region-bound.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/regions/regions-assoc-type-static-bound.rs b/src/test/ui/regions/regions-assoc-type-static-bound.rs new file mode 100644 index 00000000000..1458787ea65 --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-static-bound.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/regions/regions-borrow-at.rs b/src/test/ui/regions/regions-borrow-at.rs new file mode 100644 index 00000000000..355e8c91455 --- /dev/null +++ b/src/test/ui/regions/regions-borrow-at.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/regions/regions-borrow-evec-fixed.rs b/src/test/ui/regions/regions-borrow-evec-fixed.rs new file mode 100644 index 00000000000..ed828312b46 --- /dev/null +++ b/src/test/ui/regions/regions-borrow-evec-fixed.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/regions/regions-borrow-evec-uniq.rs b/src/test/ui/regions/regions-borrow-evec-uniq.rs new file mode 100644 index 00000000000..bbf7ba79e2a --- /dev/null +++ b/src/test/ui/regions/regions-borrow-evec-uniq.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/regions/regions-borrow-uniq.rs b/src/test/ui/regions/regions-borrow-uniq.rs new file mode 100644 index 00000000000..3bf049c1511 --- /dev/null +++ b/src/test/ui/regions/regions-borrow-uniq.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/regions/regions-bot.rs b/src/test/ui/regions/regions-bot.rs new file mode 100644 index 00000000000..58016293640 --- /dev/null +++ b/src/test/ui/regions/regions-bot.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/regions/regions-bound-lists-feature-gate-2.rs b/src/test/ui/regions/regions-bound-lists-feature-gate-2.rs new file mode 100644 index 00000000000..2c750379933 --- /dev/null +++ b/src/test/ui/regions/regions-bound-lists-feature-gate-2.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/regions/regions-bound-lists-feature-gate.rs b/src/test/ui/regions/regions-bound-lists-feature-gate.rs new file mode 100644 index 00000000000..3815498f86f --- /dev/null +++ b/src/test/ui/regions/regions-bound-lists-feature-gate.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/regions/regions-close-over-type-parameter-successfully.rs b/src/test/ui/regions/regions-close-over-type-parameter-successfully.rs new file mode 100644 index 00000000000..4b47ed8c6ae --- /dev/null +++ b/src/test/ui/regions/regions-close-over-type-parameter-successfully.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/regions/regions-copy-closure.rs b/src/test/ui/regions/regions-copy-closure.rs new file mode 100644 index 00000000000..43640079777 --- /dev/null +++ b/src/test/ui/regions/regions-copy-closure.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/regions/regions-creating-enums2.rs b/src/test/ui/regions/regions-creating-enums2.rs new file mode 100644 index 00000000000..7b16fb1a8e0 --- /dev/null +++ b/src/test/ui/regions/regions-creating-enums2.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/regions/regions-creating-enums5.rs b/src/test/ui/regions/regions-creating-enums5.rs new file mode 100644 index 00000000000..ad3d9748bf0 --- /dev/null +++ b/src/test/ui/regions/regions-creating-enums5.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/regions/regions-debruijn-of-object.rs b/src/test/ui/regions/regions-debruijn-of-object.rs new file mode 100644 index 00000000000..0b5510489fb --- /dev/null +++ b/src/test/ui/regions/regions-debruijn-of-object.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/regions/regions-dependent-addr-of.rs b/src/test/ui/regions/regions-dependent-addr-of.rs new file mode 100644 index 00000000000..0a7e6625c73 --- /dev/null +++ b/src/test/ui/regions/regions-dependent-addr-of.rs @@ -0,0 +1,113 @@ +// 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/src/test/ui/regions/regions-dependent-autofn.rs b/src/test/ui/regions/regions-dependent-autofn.rs new file mode 100644 index 00000000000..246dbb5563c --- /dev/null +++ b/src/test/ui/regions/regions-dependent-autofn.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-dependent-autoslice.rs b/src/test/ui/regions/regions-dependent-autoslice.rs new file mode 100644 index 00000000000..4c5b35ec455 --- /dev/null +++ b/src/test/ui/regions/regions-dependent-autoslice.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/regions/regions-dependent-let-ref.rs b/src/test/ui/regions/regions-dependent-let-ref.rs new file mode 100644 index 00000000000..94e3df4b3f1 --- /dev/null +++ b/src/test/ui/regions/regions-dependent-let-ref.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs new file mode 100644 index 00000000000..fe50a7dd1be --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/regions/regions-early-bound-trait-param.rs b/src/test/ui/regions/regions-early-bound-trait-param.rs new file mode 100644 index 00000000000..cc2bde78d85 --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-trait-param.rs @@ -0,0 +1,134 @@ +// 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/src/test/ui/regions/regions-early-bound-used-in-bound-method.rs b/src/test/ui/regions/regions-early-bound-used-in-bound-method.rs new file mode 100644 index 00000000000..a778dae1ed3 --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-used-in-bound-method.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/regions/regions-early-bound-used-in-bound.rs b/src/test/ui/regions/regions-early-bound-used-in-bound.rs new file mode 100644 index 00000000000..6ccc99e845d --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-used-in-bound.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/regions/regions-early-bound-used-in-type-param.rs b/src/test/ui/regions/regions-early-bound-used-in-type-param.rs new file mode 100644 index 00000000000..d58c17ad9c8 --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-used-in-type-param.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/regions/regions-escape-into-other-fn.rs b/src/test/ui/regions/regions-escape-into-other-fn.rs new file mode 100644 index 00000000000..fd4690463e6 --- /dev/null +++ b/src/test/ui/regions/regions-escape-into-other-fn.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/regions/regions-expl-self.rs b/src/test/ui/regions/regions-expl-self.rs new file mode 100644 index 00000000000..f7315d628a5 --- /dev/null +++ b/src/test/ui/regions/regions-expl-self.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-fn-subtyping-2.rs b/src/test/ui/regions/regions-fn-subtyping-2.rs new file mode 100644 index 00000000000..83949ddba3d --- /dev/null +++ b/src/test/ui/regions/regions-fn-subtyping-2.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/regions/regions-fn-subtyping.rs b/src/test/ui/regions/regions-fn-subtyping.rs new file mode 100644 index 00000000000..9570359c69e --- /dev/null +++ b/src/test/ui/regions/regions-fn-subtyping.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs new file mode 100644 index 00000000000..f464cab7554 --- /dev/null +++ b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs b/src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs new file mode 100644 index 00000000000..5d8ad932ed6 --- /dev/null +++ b/src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/regions/regions-infer-borrow-scope-view.rs b/src/test/ui/regions/regions-infer-borrow-scope-view.rs new file mode 100644 index 00000000000..349b5204434 --- /dev/null +++ b/src/test/ui/regions/regions-infer-borrow-scope-view.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs b/src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs new file mode 100644 index 00000000000..f0ecc5de545 --- /dev/null +++ b/src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/regions/regions-infer-borrow-scope.rs b/src/test/ui/regions/regions-infer-borrow-scope.rs new file mode 100644 index 00000000000..453973d9c58 --- /dev/null +++ b/src/test/ui/regions/regions-infer-borrow-scope.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-infer-call-2.rs b/src/test/ui/regions/regions-infer-call-2.rs new file mode 100644 index 00000000000..a288d2e4d6e --- /dev/null +++ b/src/test/ui/regions/regions-infer-call-2.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-infer-call.rs b/src/test/ui/regions/regions-infer-call.rs new file mode 100644 index 00000000000..248f9e923d3 --- /dev/null +++ b/src/test/ui/regions/regions-infer-call.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs b/src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs new file mode 100644 index 00000000000..fbd89501559 --- /dev/null +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs b/src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs new file mode 100644 index 00000000000..31a48b4adcf --- /dev/null +++ b/src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs b/src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs new file mode 100644 index 00000000000..6aa5d8217a4 --- /dev/null +++ b/src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/regions/regions-infer-static-from-proc.rs b/src/test/ui/regions/regions-infer-static-from-proc.rs new file mode 100644 index 00000000000..39501e2d697 --- /dev/null +++ b/src/test/ui/regions/regions-infer-static-from-proc.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/regions/regions-issue-21422.rs b/src/test/ui/regions/regions-issue-21422.rs new file mode 100644 index 00000000000..198b7146647 --- /dev/null +++ b/src/test/ui/regions/regions-issue-21422.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/regions/regions-issue-22246.rs b/src/test/ui/regions/regions-issue-22246.rs new file mode 100644 index 00000000000..0858833678b --- /dev/null +++ b/src/test/ui/regions/regions-issue-22246.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs b/src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs new file mode 100644 index 00000000000..c8106f32c65 --- /dev/null +++ b/src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs b/src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs new file mode 100644 index 00000000000..b6a89e29ecc --- /dev/null +++ b/src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/regions/regions-link-fn-args.rs b/src/test/ui/regions/regions-link-fn-args.rs new file mode 100644 index 00000000000..231407b226e --- /dev/null +++ b/src/test/ui/regions/regions-link-fn-args.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-lub-ref-ref-rc.rs b/src/test/ui/regions/regions-lub-ref-ref-rc.rs new file mode 100644 index 00000000000..96c71b084b1 --- /dev/null +++ b/src/test/ui/regions/regions-lub-ref-ref-rc.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/regions/regions-mock-codegen.rs b/src/test/ui/regions/regions-mock-codegen.rs new file mode 100644 index 00000000000..521ef3f6a4b --- /dev/null +++ b/src/test/ui/regions/regions-mock-codegen.rs @@ -0,0 +1,56 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +#![feature(allocator_api)] + +use std::alloc::{Alloc, Global, Layout, handle_alloc_error}; +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<'a>(_bcx : &'a arena) -> &'a Bcx<'a> { + 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: 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: ccx }; + return g(&fcx); +} + +pub fn main() { + let ccx = Ccx { x: 0 }; + f(&ccx); +} diff --git a/src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs b/src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs new file mode 100644 index 00000000000..aafab5d86b8 --- /dev/null +++ b/src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/regions/regions-no-variance-from-fn-generics.rs b/src/test/ui/regions/regions-no-variance-from-fn-generics.rs new file mode 100644 index 00000000000..76706a82781 --- /dev/null +++ b/src/test/ui/regions/regions-no-variance-from-fn-generics.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/regions/regions-nullary-variant.rs b/src/test/ui/regions/regions-nullary-variant.rs new file mode 100644 index 00000000000..82470af82fa --- /dev/null +++ b/src/test/ui/regions/regions-nullary-variant.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/regions/regions-params.rs b/src/test/ui/regions/regions-params.rs new file mode 100644 index 00000000000..04f3b8eaf57 --- /dev/null +++ b/src/test/ui/regions/regions-params.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/regions/regions-reassign-let-bound-pointer.rs b/src/test/ui/regions/regions-reassign-let-bound-pointer.rs new file mode 100644 index 00000000000..948b11e0f30 --- /dev/null +++ b/src/test/ui/regions/regions-reassign-let-bound-pointer.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/regions/regions-reassign-match-bound-pointer.rs b/src/test/ui/regions/regions-reassign-match-bound-pointer.rs new file mode 100644 index 00000000000..ca52659c4db --- /dev/null +++ b/src/test/ui/regions/regions-reassign-match-bound-pointer.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/regions/regions-refcell.rs b/src/test/ui/regions/regions-refcell.rs new file mode 100644 index 00000000000..39ad0c53f1e --- /dev/null +++ b/src/test/ui/regions/regions-refcell.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs b/src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs new file mode 100644 index 00000000000..aec05161c1a --- /dev/null +++ b/src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/regions/regions-return-interior-of-option.rs b/src/test/ui/regions/regions-return-interior-of-option.rs new file mode 100644 index 00000000000..2dc91ec84f5 --- /dev/null +++ b/src/test/ui/regions/regions-return-interior-of-option.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/regions/regions-scope-chain-example.rs b/src/test/ui/regions/regions-scope-chain-example.rs new file mode 100644 index 00000000000..2beb20add32 --- /dev/null +++ b/src/test/ui/regions/regions-scope-chain-example.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/regions/regions-self-impls.rs b/src/test/ui/regions/regions-self-impls.rs new file mode 100644 index 00000000000..80b88568e42 --- /dev/null +++ b/src/test/ui/regions/regions-self-impls.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/regions/regions-self-in-enums.rs b/src/test/ui/regions/regions-self-in-enums.rs new file mode 100644 index 00000000000..c2e4b2ff10d --- /dev/null +++ b/src/test/ui/regions/regions-self-in-enums.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/regions/regions-simple.rs b/src/test/ui/regions/regions-simple.rs new file mode 100644 index 00000000000..fff1b47f53f --- /dev/null +++ b/src/test/ui/regions/regions-simple.rs @@ -0,0 +1,7 @@ +// run-pass +pub fn main() { + let mut x: isize = 3; + let y: &mut isize = &mut x; + *y = 5; + println!("{}", *y); +} diff --git a/src/test/ui/regions/regions-static-closure.rs b/src/test/ui/regions/regions-static-closure.rs new file mode 100644 index 00000000000..09cd5622032 --- /dev/null +++ b/src/test/ui/regions/regions-static-closure.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/regions/regions-trait-object-1.rs b/src/test/ui/regions/regions-trait-object-1.rs new file mode 100644 index 00000000000..679bf4dd811 --- /dev/null +++ b/src/test/ui/regions/regions-trait-object-1.rs @@ -0,0 +1,35 @@ +// run-pass +// This is a regression test for something that only came up while +// attempting to bootstrap libsyntax; it is adapted from +// `syntax::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/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs b/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs new file mode 100644 index 00000000000..f10d5a25f16 --- /dev/null +++ b/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/regions/regions-variance-covariant-use-covariant.rs b/src/test/ui/regions/regions-variance-covariant-use-covariant.rs new file mode 100644 index 00000000000..9316aa15d32 --- /dev/null +++ b/src/test/ui/regions/regions-variance-covariant-use-covariant.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/repeat-expr-in-static.rs b/src/test/ui/repeat-expr-in-static.rs new file mode 100644 index 00000000000..0b895379330 --- /dev/null +++ b/src/test/ui/repeat-expr-in-static.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/repr_c_int_align.rs b/src/test/ui/repr_c_int_align.rs new file mode 100644 index 00000000000..fdd14fc2dbe --- /dev/null +++ b/src/test/ui/repr_c_int_align.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/resolve-issue-2428.rs b/src/test/ui/resolve-issue-2428.rs new file mode 100644 index 00000000000..5f3473e9feb --- /dev/null +++ b/src/test/ui/resolve-issue-2428.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/resolve-pseudo-shadowing.rs b/src/test/ui/resolve-pseudo-shadowing.rs new file mode 100644 index 00000000000..85c684ca032 --- /dev/null +++ b/src/test/ui/resolve-pseudo-shadowing.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/resource-assign-is-not-copy.rs b/src/test/ui/resource-assign-is-not-copy.rs new file mode 100644 index 00000000000..c1de139a9a9 --- /dev/null +++ b/src/test/ui/resource-assign-is-not-copy.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/resource-destruct.rs b/src/test/ui/resource-destruct.rs new file mode 100644 index 00000000000..c4756a21a00 --- /dev/null +++ b/src/test/ui/resource-destruct.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/result-opt-conversions.rs b/src/test/ui/result-opt-conversions.rs new file mode 100644 index 00000000000..57f258aab65 --- /dev/null +++ b/src/test/ui/result-opt-conversions.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/ret-bang.rs b/src/test/ui/ret-bang.rs new file mode 100644 index 00000000000..6618992e036 --- /dev/null +++ b/src/test/ui/ret-bang.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/ret-none.rs b/src/test/ui/ret-none.rs new file mode 100644 index 00000000000..d595506e336 --- /dev/null +++ b/src/test/ui/ret-none.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/return-nil.rs b/src/test/ui/return-nil.rs new file mode 100644 index 00000000000..fd5203ff0ed --- /dev/null +++ b/src/test/ui/return-nil.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f() { let x: () = (); return x; } + +pub fn main() { let _x = f(); } diff --git a/src/test/ui/rfcs/rfc-1014-2.rs b/src/test/ui/rfcs/rfc-1014-2.rs new file mode 100644 index 00000000000..5be092204d7 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1014-2.rs @@ -0,0 +1,30 @@ +// 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 world"); +} + +#[cfg(not(windows))] +fn main() {} diff --git a/src/test/ui/rfcs/rfc-1014.rs b/src/test/ui/rfcs/rfc-1014.rs new file mode 100644 index 00000000000..41a036958bf --- /dev/null +++ b/src/test/ui/rfcs/rfc-1014.rs @@ -0,0 +1,34 @@ +// 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 world"); +} diff --git a/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs b/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs new file mode 100644 index 00000000000..ea3ad7aed49 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs new file mode 100644 index 00000000000..e98582cbce3 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs @@ -0,0 +1,6 @@ +// run-pass +use std::error::Error; + +fn main() -> Result<(), Box> { + Ok(()) +} diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs new file mode 100644 index 00000000000..bac695d4e79 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs @@ -0,0 +1,2 @@ +// run-pass +fn main() {} diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs new file mode 100644 index 00000000000..9c2270bf827 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(process_exitcode_placeholder)] + +use std::process::ExitCode; + +fn main() -> ExitCode { + ExitCode::SUCCESS +} diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs new file mode 100644 index 00000000000..79cfba011c0 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs @@ -0,0 +1,4 @@ +// run-pass +#![feature(termination_trait_lib)] + +fn main() -> impl std::process::Termination { } diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs new file mode 100644 index 00000000000..b0e932e1fe0 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs @@ -0,0 +1,6 @@ +// run-pass +use std::io::Error; + +fn main() -> Result<(), Box> { + Ok(()) +} diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs new file mode 100644 index 00000000000..30f36c24489 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs @@ -0,0 +1,6 @@ +// run-pass +use std::io::Error; + +fn main() -> Result<(), Error> { + Ok(()) +} diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs new file mode 100644 index 00000000000..f0591c38c00 --- /dev/null +++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() -> Result<(), &'static str> { + Ok(()) +} diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs new file mode 100644 index 00000000000..b3be41599a5 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs new file mode 100644 index 00000000000..d5bca6a2474 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs new file mode 100644 index 00000000000..52fbb90ed54 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs new file mode 100644 index 00000000000..a5a24a80634 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs new file mode 100644 index 00000000000..0207f607be8 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs @@ -0,0 +1,249 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs new file mode 100644 index 00000000000..9379753598e --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs new file mode 100644 index 00000000000..580e67513b3 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs @@ -0,0 +1,9 @@ +// run-pass +pub fn main() { + let i = 5; + match &&&&i { + 1 ..= 3 => panic!(), + 3 ..= 8 => {}, + _ => panic!(), + } +} diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs new file mode 100644 index 00000000000..b74e45c9328 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs new file mode 100644 index 00000000000..3b9d07610d2 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs new file mode 100644 index 00000000000..939a3c4a1fd --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -0,0 +1,26 @@ +// run-pass +#![feature(slice_patterns)] + +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/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs new file mode 100644 index 00000000000..5a00e5b6823 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs new file mode 100644 index 00000000000..0cf9ba1b4ca --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs new file mode 100644 index 00000000000..4c22aa2d718 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs new file mode 100644 index 00000000000..2fe1e05e509 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs new file mode 100644 index 00000000000..f2fe59668da --- /dev/null +++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs new file mode 100644 index 00000000000..4665225178c --- /dev/null +++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs new file mode 100644 index 00000000000..0ab7e17f87b --- /dev/null +++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs b/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs new file mode 100644 index 00000000000..22f04c58f3b --- /dev/null +++ b/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs b/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs new file mode 100644 index 00000000000..1ec20c50034 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs @@ -0,0 +1,127 @@ +// 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/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs new file mode 100644 index 00000000000..6d7bca4da24 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs new file mode 100644 index 00000000000..17174e22c74 --- /dev/null +++ b/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/rfcs/rfc1445/eq-allows-match.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match.rs new file mode 100644 index 00000000000..405a69c94bf --- /dev/null +++ b/src/test/ui/rfcs/rfc1445/eq-allows-match.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/rfcs/rfc1623.rs b/src/test/ui/rfcs/rfc1623.rs new file mode 100644 index 00000000000..adaf25c6bbf --- /dev/null +++ b/src/test/ui/rfcs/rfc1623.rs @@ -0,0 +1,75 @@ +// 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/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs new file mode 100644 index 00000000000..c1c5b70bc04 --- /dev/null +++ b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs @@ -0,0 +1,5 @@ +// no-prefer-dynamic +#![crate_type = "staticlib"] + +#[no_mangle] +pub extern "C" fn foo(x:i32) -> i32 { x } diff --git a/src/test/ui/rfcs/rfc1717/library-override.rs b/src/test/ui/rfcs/rfc1717/library-override.rs new file mode 100644 index 00000000000..014ccac31b7 --- /dev/null +++ b/src/test/ui/rfcs/rfc1717/library-override.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/rfcs/rfc1857-drop-order.rs b/src/test/ui/rfcs/rfc1857-drop-order.rs new file mode 100644 index 00000000000..7923aa7c0e2 --- /dev/null +++ b/src/test/ui/rfcs/rfc1857-drop-order.rs @@ -0,0 +1,224 @@ +// 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/src/test/ui/running-with-no-runtime.rs b/src/test/ui/running-with-no-runtime.rs new file mode 100644 index 00000000000..3fc631be60e --- /dev/null +++ b/src/test/ui/running-with-no-runtime.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/rustc-rust-log.rs b/src/test/ui/rustc-rust-log.rs new file mode 100644 index 00000000000..1c4252b23ea --- /dev/null +++ b/src/test/ui/rustc-rust-log.rs @@ -0,0 +1,14 @@ +// 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 + +// rustc-env:RUSTC_LOG=debug + +fn main() {} diff --git a/src/test/ui/rvalue-static-promotion.rs b/src/test/ui/rvalue-static-promotion.rs new file mode 100644 index 00000000000..2d7e4ab3989 --- /dev/null +++ b/src/test/ui/rvalue-static-promotion.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/segfault-no-out-of-stack.rs b/src/test/ui/segfault-no-out-of-stack.rs new file mode 100644 index 00000000000..626de4ed5b6 --- /dev/null +++ b/src/test/ui/segfault-no-out-of-stack.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/semistatement-in-lambda.rs b/src/test/ui/semistatement-in-lambda.rs new file mode 100644 index 00000000000..ebd55e0ba02 --- /dev/null +++ b/src/test/ui/semistatement-in-lambda.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs new file mode 100644 index 00000000000..73fb5e8f3c4 --- /dev/null +++ b/src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn foo() -> usize { + 1234 +} diff --git a/src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs new file mode 100644 index 00000000000..64e34a56da4 --- /dev/null +++ b/src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs @@ -0,0 +1,6 @@ +#[inline] +pub fn cci_fn() -> usize { + 1200 +} + +pub const CCI_CONST: usize = 34; diff --git a/src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs new file mode 100644 index 00000000000..1536228c265 --- /dev/null +++ b/src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/sepcomp/sepcomp-cci.rs b/src/test/ui/sepcomp/sepcomp-cci.rs new file mode 100644 index 00000000000..02bbab30e9c --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-cci.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/sepcomp/sepcomp-extern.rs b/src/test/ui/sepcomp/sepcomp-extern.rs new file mode 100644 index 00000000000..c4ccf23c47a --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-extern.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/sepcomp/sepcomp-fns-backwards.rs b/src/test/ui/sepcomp/sepcomp-fns-backwards.rs new file mode 100644 index 00000000000..f56769e2b8c --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-fns-backwards.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/sepcomp/sepcomp-fns.rs b/src/test/ui/sepcomp/sepcomp-fns.rs new file mode 100644 index 00000000000..a432c89606e --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-fns.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/sepcomp/sepcomp-lib-lto.rs b/src/test/ui/sepcomp/sepcomp-lib-lto.rs new file mode 100644 index 00000000000..164ae79c254 --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-lib-lto.rs @@ -0,0 +1,18 @@ +// 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 +// 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/src/test/ui/sepcomp/sepcomp-lib.rs b/src/test/ui/sepcomp/sepcomp-lib.rs new file mode 100644 index 00000000000..728dc078b7e --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-lib.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/sepcomp/sepcomp-statics.rs b/src/test/ui/sepcomp/sepcomp-statics.rs new file mode 100644 index 00000000000..5457c8a0ae9 --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-statics.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/sepcomp/sepcomp-unwind.rs b/src/test/ui/sepcomp/sepcomp-unwind.rs new file mode 100644 index 00000000000..50a4e043943 --- /dev/null +++ b/src/test/ui/sepcomp/sepcomp-unwind.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/seq-compare.rs b/src/test/ui/seq-compare.rs new file mode 100644 index 00000000000..4078326b559 --- /dev/null +++ b/src/test/ui/seq-compare.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/shadow.rs b/src/test/ui/shadow.rs new file mode 100644 index 00000000000..2495c8f47e7 --- /dev/null +++ b/src/test/ui/shadow.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/shadowed-use-visibility.rs b/src/test/ui/shadowed-use-visibility.rs new file mode 100644 index 00000000000..350fbfeaeb5 --- /dev/null +++ b/src/test/ui/shadowed-use-visibility.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/shebang.rs b/src/test/ui/shebang.rs new file mode 100644 index 00000000000..3d3ba468be9 --- /dev/null +++ b/src/test/ui/shebang.rs @@ -0,0 +1,5 @@ +#!/usr/bin/env rustx + +// run-pass + +pub fn main() { println!("Hello World"); } diff --git a/src/test/ui/signal-alternate-stack-cleanup.rs b/src/test/ui/signal-alternate-stack-cleanup.rs new file mode 100644 index 00000000000..787ff51799a --- /dev/null +++ b/src/test/ui/signal-alternate-stack-cleanup.rs @@ -0,0 +1,37 @@ +// 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 + +#![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/src/test/ui/signal-exit-status.rs b/src/test/ui/signal-exit-status.rs new file mode 100644 index 00000000000..bd34a218160 --- /dev/null +++ b/src/test/ui/signal-exit-status.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/sigpipe-should-be-ignored.rs b/src/test/ui/sigpipe-should-be-ignored.rs new file mode 100644 index 00000000000..f472029b820 --- /dev/null +++ b/src/test/ui/sigpipe-should-be-ignored.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/simd/simd-generics.rs b/src/test/ui/simd/simd-generics.rs new file mode 100644 index 00000000000..ab6caee9d7b --- /dev/null +++ b/src/test/ui/simd/simd-generics.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/simd/simd-intrinsic-float-math.rs b/src/test/ui/simd/simd-intrinsic-float-math.rs new file mode 100644 index 00000000000..220a59535ca --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-float-math.rs @@ -0,0 +1,103 @@ +// 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/src/test/ui/simd/simd-intrinsic-float-minmax.rs b/src/test/ui/simd/simd-intrinsic-float-minmax.rs new file mode 100644 index 00000000000..350bc434935 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-float-minmax.rs @@ -0,0 +1,54 @@ +// run-pass +// ignore-emscripten +// min-llvm-version 7.0 +// error-pattern: panicked + +// 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/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs new file mode 100644 index 00000000000..b2ddcf023eb --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs @@ -0,0 +1,92 @@ +// run-pass +// ignore-emscripten +// min-llvm-version 8.0 + +#![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_value(); + + 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_value(); + const MAX: i32 = i32::max_value(); + + 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/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs new file mode 100644 index 00000000000..b67c0ad1eb2 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs @@ -0,0 +1,120 @@ +// 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/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 00000000000..b28f742a92e --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,61 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten + +// 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_value(), 0, usize::max_value(), usize::max_value()); + + 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/src/test/ui/simd/simd-intrinsic-generic-cast.rs b/src/test/ui/simd/simd-intrinsic-generic-cast.rs new file mode 100644 index 00000000000..15f232e2c0f --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-cast.rs @@ -0,0 +1,121 @@ +// 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/src/test/ui/simd/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd/simd-intrinsic-generic-comparison.rs new file mode 100644 index 00000000000..2b593e1c9b8 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-comparison.rs @@ -0,0 +1,106 @@ +// 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/src/test/ui/simd/simd-intrinsic-generic-elements.rs b/src/test/ui/simd/simd-intrinsic-generic-elements.rs new file mode 100644 index 00000000000..ea3d4b18944 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-elements.rs @@ -0,0 +1,125 @@ +// 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/src/test/ui/simd/simd-intrinsic-generic-gather.rs b/src/test/ui/simd/simd-intrinsic-generic-gather.rs new file mode 100644 index 00000000000..805caebe5b1 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-gather.rs @@ -0,0 +1,141 @@ +// 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/src/test/ui/simd/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs new file mode 100644 index 00000000000..4195444a73f --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,165 @@ +// 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_value(); + 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/src/test/ui/simd/simd-intrinsic-generic-select.rs b/src/test/ui/simd/simd-intrinsic-generic-select.rs new file mode 100644 index 00000000000..22bda4fc9d9 --- /dev/null +++ b/src/test/ui/simd/simd-intrinsic-generic-select.rs @@ -0,0 +1,173 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten +// ignore-mips behavior of simd_select_bitmask is endian-specific +// ignore-mips64 behavior of simd_select_bitmask is endian-specific +// ignore-powerpc behavior of simd_select_bitmask is endian-specific +// ignore-powerpc64 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); + } +} diff --git a/src/test/ui/simd/simd-size-align.rs b/src/test/ui/simd/simd-size-align.rs new file mode 100644 index 00000000000..556013788c3 --- /dev/null +++ b/src/test/ui/simd/simd-size-align.rs @@ -0,0 +1,96 @@ +// 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/src/test/ui/simd/simd-target-feature-mixup.rs b/src/test/ui/simd/simd-target-feature-mixup.rs new file mode 100644 index 00000000000..6d7688191b7 --- /dev/null +++ b/src/test/ui/simd/simd-target-feature-mixup.rs @@ -0,0 +1,185 @@ +// 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/src/test/ui/simd/simd-type.rs b/src/test/ui/simd/simd-type.rs new file mode 100644 index 00000000000..e7b9bfe32f8 --- /dev/null +++ b/src/test/ui/simd/simd-type.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/simple-infer.rs b/src/test/ui/simple-infer.rs new file mode 100644 index 00000000000..561e4fdec7c --- /dev/null +++ b/src/test/ui/simple-infer.rs @@ -0,0 +1,6 @@ +// run-pass + +#![allow(unused_mut)] + + +pub fn main() { let mut n; n = 1; println!("{}", n); } diff --git a/src/test/ui/simple_global_asm.rs b/src/test/ui/simple_global_asm.rs new file mode 100644 index 00000000000..d95fefebc0f --- /dev/null +++ b/src/test/ui/simple_global_asm.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/size-and-align.rs b/src/test/ui/size-and-align.rs new file mode 100644 index 00000000000..a32b5de7292 --- /dev/null +++ b/src/test/ui/size-and-align.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/sized-borrowed-pointer.rs b/src/test/ui/sized-borrowed-pointer.rs new file mode 100644 index 00000000000..319b8026954 --- /dev/null +++ b/src/test/ui/sized-borrowed-pointer.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/sized-owned-pointer.rs b/src/test/ui/sized-owned-pointer.rs new file mode 100644 index 00000000000..2abf0a1e0c2 --- /dev/null +++ b/src/test/ui/sized-owned-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::>() } +pub fn main() { } diff --git a/src/test/ui/sleep.rs b/src/test/ui/sleep.rs new file mode 100644 index 00000000000..757578b8475 --- /dev/null +++ b/src/test/ui/sleep.rs @@ -0,0 +1,19 @@ +// run-pass +// ignore-emscripten no threads support +// ignore-sgx no thread sleep 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/src/test/ui/slowparse-bstring.rs b/src/test/ui/slowparse-bstring.rs new file mode 100644 index 00000000000..f3a6a668372 --- /dev/null +++ b/src/test/ui/slowparse-bstring.rs @@ -0,0 +1,6 @@ +// run-pass +// ignore-tidy-linelength + +// Issue #16624 + +fn main() { b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } diff --git a/src/test/ui/slowparse-string.rs b/src/test/ui/slowparse-string.rs new file mode 100644 index 00000000000..6ebc61dae78 --- /dev/null +++ b/src/test/ui/slowparse-string.rs @@ -0,0 +1,6 @@ +// run-pass +// ignore-tidy-linelength + +// Issue #16624 + +fn main() { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } diff --git a/src/test/ui/specialization/assoc-ty-graph-cycle.rs b/src/test/ui/specialization/assoc-ty-graph-cycle.rs new file mode 100644 index 00000000000..54d51492ab3 --- /dev/null +++ b/src/test/ui/specialization/assoc-ty-graph-cycle.rs @@ -0,0 +1,25 @@ +// run-pass + +// Make sure we don't crash with a cycle error during coherence. + +#![feature(specialization)] + +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/src/test/ui/specialization/auxiliary/cross_crates_defaults.rs b/src/test/ui/specialization/auxiliary/cross_crates_defaults.rs new file mode 100644 index 00000000000..5cf975b5752 --- /dev/null +++ b/src/test/ui/specialization/auxiliary/cross_crates_defaults.rs @@ -0,0 +1,38 @@ +#![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 {} // use the provided method + +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/src/test/ui/specialization/auxiliary/go_trait.rs b/src/test/ui/specialization/auxiliary/go_trait.rs new file mode 100644 index 00000000000..aa0ec22896d --- /dev/null +++ b/src/test/ui/specialization/auxiliary/go_trait.rs @@ -0,0 +1,43 @@ +#![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/src/test/ui/specialization/auxiliary/specialization_cross_crate.rs b/src/test/ui/specialization/auxiliary/specialization_cross_crate.rs new file mode 100644 index 00000000000..8caa8524fb9 --- /dev/null +++ b/src/test/ui/specialization/auxiliary/specialization_cross_crate.rs @@ -0,0 +1,72 @@ +#![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/src/test/ui/specialization/cross-crate-defaults.rs b/src/test/ui/specialization/cross-crate-defaults.rs new file mode 100644 index 00000000000..79cb6594397 --- /dev/null +++ b/src/test/ui/specialization/cross-crate-defaults.rs @@ -0,0 +1,41 @@ +// run-pass + +// aux-build:cross_crates_defaults.rs + +#![feature(specialization)] + +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/src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs new file mode 100644 index 00000000000..15550bcce2a --- /dev/null +++ b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] + +// aux-build:go_trait.rs + +#![feature(specialization)] + +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/src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs b/src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs new file mode 100644 index 00000000000..c065593b432 --- /dev/null +++ b/src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs @@ -0,0 +1,43 @@ +#![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/src/test/ui/specialization/defaultimpl/out-of-order.rs b/src/test/ui/specialization/defaultimpl/out-of-order.rs new file mode 100644 index 00000000000..f9c73a19cfa --- /dev/null +++ b/src/test/ui/specialization/defaultimpl/out-of-order.rs @@ -0,0 +1,19 @@ +// run-pass + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +default impl Foo for T { + type Out = bool; +} + +fn main() {} diff --git a/src/test/ui/specialization/defaultimpl/overlap-projection.rs b/src/test/ui/specialization/defaultimpl/overlap-projection.rs new file mode 100644 index 00000000000..ed38bb3fc3a --- /dev/null +++ b/src/test/ui/specialization/defaultimpl/overlap-projection.rs @@ -0,0 +1,25 @@ +// 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)] + +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/src/test/ui/specialization/defaultimpl/projection.rs b/src/test/ui/specialization/defaultimpl/projection.rs new file mode 100644 index 00000000000..897a7aade2f --- /dev/null +++ b/src/test/ui/specialization/defaultimpl/projection.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] + +// 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/src/test/ui/specialization/issue-50452.rs b/src/test/ui/specialization/issue-50452.rs new file mode 100644 index 00000000000..93f081d9558 --- /dev/null +++ b/src/test/ui/specialization/issue-50452.rs @@ -0,0 +1,19 @@ +// run-pass + +#![feature(specialization)] + +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/src/test/ui/specialization/specialization-allowed-cross-crate.rs b/src/test/ui/specialization/specialization-allowed-cross-crate.rs new file mode 100644 index 00000000000..15550bcce2a --- /dev/null +++ b/src/test/ui/specialization/specialization-allowed-cross-crate.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] + +// aux-build:go_trait.rs + +#![feature(specialization)] + +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/src/test/ui/specialization/specialization-assoc-fns.rs b/src/test/ui/specialization/specialization-assoc-fns.rs new file mode 100644 index 00000000000..b6a7a48972a --- /dev/null +++ b/src/test/ui/specialization/specialization-assoc-fns.rs @@ -0,0 +1,29 @@ +// run-pass + +// Test that non-method associated functions can be specialized + +#![feature(specialization)] + +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/src/test/ui/specialization/specialization-basics.rs b/src/test/ui/specialization/specialization-basics.rs new file mode 100644 index 00000000000..6c359e51bc2 --- /dev/null +++ b/src/test/ui/specialization/specialization-basics.rs @@ -0,0 +1,98 @@ +// run-pass + +#![feature(specialization)] + +// 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/src/test/ui/specialization/specialization-cross-crate-no-gate.rs b/src/test/ui/specialization/specialization-cross-crate-no-gate.rs new file mode 100644 index 00000000000..f744b16de7a --- /dev/null +++ b/src/test/ui/specialization/specialization-cross-crate-no-gate.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/specialization/specialization-cross-crate.rs b/src/test/ui/specialization/specialization-cross-crate.rs new file mode 100644 index 00000000000..fa63c866329 --- /dev/null +++ b/src/test/ui/specialization/specialization-cross-crate.rs @@ -0,0 +1,50 @@ +// run-pass + +// aux-build:specialization_cross_crate.rs + +#![feature(specialization)] + +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/src/test/ui/specialization/specialization-default-methods.rs b/src/test/ui/specialization/specialization-default-methods.rs new file mode 100644 index 00000000000..5d65a0457e7 --- /dev/null +++ b/src/test/ui/specialization/specialization-default-methods.rs @@ -0,0 +1,86 @@ +// run-pass + +#![feature(specialization)] + +// 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 + +// use the provided method +impl Bar for T {} + +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/src/test/ui/specialization/specialization-on-projection.rs b/src/test/ui/specialization/specialization-on-projection.rs new file mode 100644 index 00000000000..5606eaea307 --- /dev/null +++ b/src/test/ui/specialization/specialization-on-projection.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] + +// 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/src/test/ui/specialization/specialization-out-of-order.rs b/src/test/ui/specialization/specialization-out-of-order.rs new file mode 100644 index 00000000000..94e764f7636 --- /dev/null +++ b/src/test/ui/specialization/specialization-out-of-order.rs @@ -0,0 +1,19 @@ +// run-pass + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +impl Foo for T { + default type Out = bool; +} + +fn main() {} diff --git a/src/test/ui/specialization/specialization-overlap-projection.rs b/src/test/ui/specialization/specialization-overlap-projection.rs new file mode 100644 index 00000000000..00b83c7e7a1 --- /dev/null +++ b/src/test/ui/specialization/specialization-overlap-projection.rs @@ -0,0 +1,25 @@ +// 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)] + +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/src/test/ui/specialization/specialization-projection-alias.rs b/src/test/ui/specialization/specialization-projection-alias.rs new file mode 100644 index 00000000000..0081ed455c9 --- /dev/null +++ b/src/test/ui/specialization/specialization-projection-alias.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +#![feature(specialization)] + +// 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/src/test/ui/specialization/specialization-projection.rs b/src/test/ui/specialization/specialization-projection.rs new file mode 100644 index 00000000000..86cdccf131e --- /dev/null +++ b/src/test/ui/specialization/specialization-projection.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] + +// 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/src/test/ui/specialization/specialization-super-traits.rs b/src/test/ui/specialization/specialization-super-traits.rs new file mode 100644 index 00000000000..a0f71d87693 --- /dev/null +++ b/src/test/ui/specialization/specialization-super-traits.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(specialization)] + +// 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/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs new file mode 100644 index 00000000000..2e32e3ff02d --- /dev/null +++ b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs @@ -0,0 +1,33 @@ +// run-pass + +#![feature(specialization)] + +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/src/test/ui/specialization/specialization-translate-projections-with-params.rs b/src/test/ui/specialization/specialization-translate-projections-with-params.rs new file mode 100644 index 00000000000..bdc6501df44 --- /dev/null +++ b/src/test/ui/specialization/specialization-translate-projections-with-params.rs @@ -0,0 +1,32 @@ +// 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)] + +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/src/test/ui/specialization/specialization-translate-projections.rs b/src/test/ui/specialization/specialization-translate-projections.rs new file mode 100644 index 00000000000..fcccb67902e --- /dev/null +++ b/src/test/ui/specialization/specialization-translate-projections.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. + +#![feature(specialization)] + +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/src/test/ui/sse2.rs b/src/test/ui/sse2.rs new file mode 100644 index 00000000000..74f112464c7 --- /dev/null +++ b/src/test/ui/sse2.rs @@ -0,0 +1,26 @@ +// 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 -- whitelisted 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/src/test/ui/stable-addr-of.rs b/src/test/ui/stable-addr-of.rs new file mode 100644 index 00000000000..99839166e30 --- /dev/null +++ b/src/test/ui/stable-addr-of.rs @@ -0,0 +1,8 @@ +// run-pass +// Issue #2040 + + +pub fn main() { + let foo: isize = 1; + assert_eq!(&foo as *const isize, &foo as *const isize); +} diff --git a/src/test/ui/stack-probes-lto.rs b/src/test/ui/stack-probes-lto.rs new file mode 100644 index 00000000000..9018ff4bfc2 --- /dev/null +++ b/src/test/ui/stack-probes-lto.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/stack-probes.rs b/src/test/ui/stack-probes.rs new file mode 100644 index 00000000000..1ab1d6df66d --- /dev/null +++ b/src/test/ui/stack-probes.rs @@ -0,0 +1,68 @@ +// 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 + +use std::mem; +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(&[]), + "child-thread" => thread::spawn(|| recurse(&[])).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: &[u64]) { + unsafe { black_box(array.as_ptr() as u64); } + #[allow(deprecated)] + let local: [_; 1024] = unsafe { mem::uninitialized() }; + 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/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs b/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs new file mode 100644 index 00000000000..4dfc25764a4 --- /dev/null +++ b/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs @@ -0,0 +1,4 @@ +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/src/test/ui/statics/auxiliary/static-methods-crate.rs b/src/test/ui/statics/auxiliary/static-methods-crate.rs new file mode 100644 index 00000000000..7ff3bc0dd2a --- /dev/null +++ b/src/test/ui/statics/auxiliary/static-methods-crate.rs @@ -0,0 +1,29 @@ +#![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/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs new file mode 100644 index 00000000000..8d0f7f61ced --- /dev/null +++ b/src/test/ui/statics/auxiliary/static_fn_inline_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 { + #[inline] + fn from_int2(n: isize) -> f64 { return n as f64; } + } +} diff --git a/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs new file mode 100644 index 00000000000..b8aed2c5f54 --- /dev/null +++ b/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs @@ -0,0 +1,11 @@ +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/src/test/ui/statics/auxiliary/static_mut_xc.rs b/src/test/ui/statics/auxiliary/static_mut_xc.rs new file mode 100644 index 00000000000..264a2243adc --- /dev/null +++ b/src/test/ui/statics/auxiliary/static_mut_xc.rs @@ -0,0 +1 @@ +pub static mut a: isize = 3; diff --git a/src/test/ui/statics/static-fn-inline-xc.rs b/src/test/ui/statics/static-fn-inline-xc.rs new file mode 100644 index 00000000000..a400b9c8d56 --- /dev/null +++ b/src/test/ui/statics/static-fn-inline-xc.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/statics/static-fn-trait-xc.rs b/src/test/ui/statics/static-fn-trait-xc.rs new file mode 100644 index 00000000000..1d3126128c9 --- /dev/null +++ b/src/test/ui/statics/static-fn-trait-xc.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/statics/static-function-pointer-xc.rs b/src/test/ui/statics/static-function-pointer-xc.rs new file mode 100644 index 00000000000..2d063a751ca --- /dev/null +++ b/src/test/ui/statics/static-function-pointer-xc.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/statics/static-function-pointer.rs b/src/test/ui/statics/static-function-pointer.rs new file mode 100644 index 00000000000..6c52dfecdec --- /dev/null +++ b/src/test/ui/statics/static-function-pointer.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/statics/static-impl.rs b/src/test/ui/statics/static-impl.rs new file mode 100644 index 00000000000..e7bdb38ee62 --- /dev/null +++ b/src/test/ui/statics/static-impl.rs @@ -0,0 +1,66 @@ +// 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/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs b/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs new file mode 100644 index 00000000000..cd3ccfee06f --- /dev/null +++ b/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/statics/static-method-xcrate.rs b/src/test/ui/statics/static-method-xcrate.rs new file mode 100644 index 00000000000..1d1cb381095 --- /dev/null +++ b/src/test/ui/statics/static-method-xcrate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/statics/static-methods-in-traits.rs b/src/test/ui/statics/static-methods-in-traits.rs new file mode 100644 index 00000000000..ff76d4e4a20 --- /dev/null +++ b/src/test/ui/statics/static-methods-in-traits.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/statics/static-methods-in-traits2.rs b/src/test/ui/statics/static-methods-in-traits2.rs new file mode 100644 index 00000000000..2c43ff6a788 --- /dev/null +++ b/src/test/ui/statics/static-methods-in-traits2.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/statics/static-mut-foreign.rs b/src/test/ui/statics/static-mut-foreign.rs new file mode 100644 index 00000000000..5d6fa416b98 --- /dev/null +++ b/src/test/ui/statics/static-mut-foreign.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/statics/static-mut-xc.rs b/src/test/ui/statics/static-mut-xc.rs new file mode 100644 index 00000000000..1d172d26a59 --- /dev/null +++ b/src/test/ui/statics/static-mut-xc.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/statics/static-recursive.rs b/src/test/ui/statics/static-recursive.rs new file mode 100644 index 00000000000..95dadc81f81 --- /dev/null +++ b/src/test/ui/statics/static-recursive.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/stdio-is-blocking.rs b/src/test/ui/stdio-is-blocking.rs new file mode 100644 index 00000000000..e96406e46b5 --- /dev/null +++ b/src/test/ui/stdio-is-blocking.rs @@ -0,0 +1,85 @@ +// 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/src/test/ui/str-concat.rs b/src/test/ui/str-concat.rs new file mode 100644 index 00000000000..fa2fc97d7b8 --- /dev/null +++ b/src/test/ui/str-concat.rs @@ -0,0 +1,9 @@ +// run-pass + +pub fn main() { + let a: String = "hello".to_string(); + let b: String = "world".to_string(); + let s: String = format!("{}{}", a, b); + println!("{}", s.clone()); + assert_eq!(s.as_bytes()[9], 'd' as u8); +} diff --git a/src/test/ui/str-multiline.rs b/src/test/ui/str-multiline.rs new file mode 100644 index 00000000000..2b2e001d8bb --- /dev/null +++ b/src/test/ui/str-multiline.rs @@ -0,0 +1,13 @@ +// run-pass + +pub fn main() { + let a: String = "this \ +is a test".to_string(); + let b: String = + "this \ + is \ + another \ + test".to_string(); + assert_eq!(a, "this is a test".to_string()); + assert_eq!(b, "this is another test".to_string()); +} diff --git a/src/test/ui/string-box-error.rs b/src/test/ui/string-box-error.rs new file mode 100644 index 00000000000..11a5bd07c3b --- /dev/null +++ b/src/test/ui/string-box-error.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/string-escapes.rs b/src/test/ui/string-escapes.rs new file mode 100644 index 00000000000..cee5e27786c --- /dev/null +++ b/src/test/ui/string-escapes.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + let x = "\\\\\ + "; + assert_eq!(x, r"\\"); // extraneous whitespace stripped +} diff --git a/src/test/ui/struct-ctor-mangling.rs b/src/test/ui/struct-ctor-mangling.rs new file mode 100644 index 00000000000..f242cb8457f --- /dev/null +++ b/src/test/ui/struct-ctor-mangling.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/structs-enums/align-enum.rs b/src/test/ui/structs-enums/align-enum.rs new file mode 100644 index 00000000000..fa872caa3b4 --- /dev/null +++ b/src/test/ui/structs-enums/align-enum.rs @@ -0,0 +1,54 @@ +// 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/src/test/ui/structs-enums/align-struct.rs b/src/test/ui/structs-enums/align-struct.rs new file mode 100644 index 00000000000..27ef990aa90 --- /dev/null +++ b/src/test/ui/structs-enums/align-struct.rs @@ -0,0 +1,245 @@ +// 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/src/test/ui/structs-enums/auxiliary/cci_class.rs b/src/test/ui/structs-enums/auxiliary/cci_class.rs new file mode 100644 index 00000000000..de2945d7460 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class.rs @@ -0,0 +1,14 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_2.rs b/src/test/ui/structs-enums/auxiliary/cci_class_2.rs new file mode 100644 index 00000000000..c3de3150e69 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_2.rs @@ -0,0 +1,19 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_3.rs b/src/test/ui/structs-enums/auxiliary/cci_class_3.rs new file mode 100644 index 00000000000..fb7fad0b5a2 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_3.rs @@ -0,0 +1,19 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_4.rs b/src/test/ui/structs-enums/auxiliary/cci_class_4.rs new file mode 100644 index 00000000000..85aa3bc8c0d --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_4.rs @@ -0,0 +1,41 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_6.rs b/src/test/ui/structs-enums/auxiliary/cci_class_6.rs new file mode 100644 index 00000000000..35f93d0c6c8 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_6.rs @@ -0,0 +1,25 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_cast.rs b/src/test/ui/structs-enums/auxiliary/cci_class_cast.rs new file mode 100644 index 00000000000..dfc3c56ddee --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_cast.rs @@ -0,0 +1,50 @@ +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/src/test/ui/structs-enums/auxiliary/cci_class_trait.rs b/src/test/ui/structs-enums/auxiliary/cci_class_trait.rs new file mode 100644 index 00000000000..2d02b591c55 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/cci_class_trait.rs @@ -0,0 +1,5 @@ +pub mod animals { + pub trait noisy { + fn speak(&mut self); + } +} diff --git a/src/test/ui/structs-enums/auxiliary/empty-struct.rs b/src/test/ui/structs-enums/auxiliary/empty-struct.rs new file mode 100644 index 00000000000..93275e7143e --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/empty-struct.rs @@ -0,0 +1,9 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty7(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty6(), +} diff --git a/src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs new file mode 100644 index 00000000000..55e6b34aca7 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs @@ -0,0 +1,25 @@ +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/src/test/ui/structs-enums/auxiliary/namespaced_enums.rs b/src/test/ui/structs-enums/auxiliary/namespaced_enums.rs new file mode 100644 index 00000000000..d3548c76cf2 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/namespaced_enums.rs @@ -0,0 +1,10 @@ +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} diff --git a/src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs b/src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs new file mode 100644 index 00000000000..9d1e0742e3c --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub struct Au(pub isize); diff --git a/src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs b/src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs new file mode 100644 index 00000000000..3665ae7e8d3 --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs @@ -0,0 +1,6 @@ +#![crate_type="lib"] + +pub struct S { + pub x: isize, + pub y: isize, +} diff --git a/src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs b/src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs new file mode 100644 index 00000000000..e919df611cf --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs @@ -0,0 +1,8 @@ +#![crate_name="struct_variant_xc_aux"] +#![crate_type = "lib"] + +#[derive(Copy, Clone)] +pub enum Enum { + Variant(u8), + StructVariant { arg: u8 } +} diff --git a/src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs b/src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs new file mode 100644 index 00000000000..bc8879aa37e --- /dev/null +++ b/src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs @@ -0,0 +1,6 @@ +pub struct S { + pub x: isize, + pub y: isize, +} + +pub type S2 = S; diff --git a/src/test/ui/structs-enums/borrow-tuple-fields.rs b/src/test/ui/structs-enums/borrow-tuple-fields.rs new file mode 100644 index 00000000000..b1d8f91646b --- /dev/null +++ b/src/test/ui/structs-enums/borrow-tuple-fields.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs b/src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs new file mode 100644 index 00000000000..bf1ba8a643f --- /dev/null +++ b/src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs b/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs new file mode 100644 index 00000000000..55975cbdb53 --- /dev/null +++ b/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs @@ -0,0 +1,93 @@ +// 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/src/test/ui/structs-enums/class-cast-to-trait.rs b/src/test/ui/structs-enums/class-cast-to-trait.rs new file mode 100644 index 00000000000..1019bb30015 --- /dev/null +++ b/src/test/ui/structs-enums/class-cast-to-trait.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/structs-enums/class-dtor.rs b/src/test/ui/structs-enums/class-dtor.rs new file mode 100644 index 00000000000..ee1cac03c81 --- /dev/null +++ b/src/test/ui/structs-enums/class-dtor.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/structs-enums/class-exports.rs b/src/test/ui/structs-enums/class-exports.rs new file mode 100644 index 00000000000..ee20887cbfb --- /dev/null +++ b/src/test/ui/structs-enums/class-exports.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs b/src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs new file mode 100644 index 00000000000..5e7830296da --- /dev/null +++ b/src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs @@ -0,0 +1,107 @@ +// 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/src/test/ui/structs-enums/class-implement-trait-cross-crate.rs b/src/test/ui/structs-enums/class-implement-trait-cross-crate.rs new file mode 100644 index 00000000000..31b79517566 --- /dev/null +++ b/src/test/ui/structs-enums/class-implement-trait-cross-crate.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/structs-enums/class-implement-traits.rs b/src/test/ui/structs-enums/class-implement-traits.rs new file mode 100644 index 00000000000..c9e98e21b9e --- /dev/null +++ b/src/test/ui/structs-enums/class-implement-traits.rs @@ -0,0 +1,63 @@ +// 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/src/test/ui/structs-enums/class-method-cross-crate.rs b/src/test/ui/structs-enums/class-method-cross-crate.rs new file mode 100644 index 00000000000..519f0685fdf --- /dev/null +++ b/src/test/ui/structs-enums/class-method-cross-crate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/structs-enums/class-methods-cross-crate.rs b/src/test/ui/structs-enums/class-methods-cross-crate.rs new file mode 100644 index 00000000000..c342af31351 --- /dev/null +++ b/src/test/ui/structs-enums/class-methods-cross-crate.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/structs-enums/class-methods.rs b/src/test/ui/structs-enums/class-methods.rs new file mode 100644 index 00000000000..83f4a5fd39e --- /dev/null +++ b/src/test/ui/structs-enums/class-methods.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/structs-enums/class-poly-methods-cross-crate.rs b/src/test/ui/structs-enums/class-poly-methods-cross-crate.rs new file mode 100644 index 00000000000..0307ba78d02 --- /dev/null +++ b/src/test/ui/structs-enums/class-poly-methods-cross-crate.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/structs-enums/class-poly-methods.rs b/src/test/ui/structs-enums/class-poly-methods.rs new file mode 100644 index 00000000000..da2870b58a4 --- /dev/null +++ b/src/test/ui/structs-enums/class-poly-methods.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/structs-enums/class-separate-impl.rs b/src/test/ui/structs-enums/class-separate-impl.rs new file mode 100644 index 00000000000..947690b51f4 --- /dev/null +++ b/src/test/ui/structs-enums/class-separate-impl.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/structs-enums/class-str-field.rs b/src/test/ui/structs-enums/class-str-field.rs new file mode 100644 index 00000000000..a3dc66aab12 --- /dev/null +++ b/src/test/ui/structs-enums/class-str-field.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/structs-enums/class-typarams.rs b/src/test/ui/structs-enums/class-typarams.rs new file mode 100644 index 00000000000..4b2d4b12ec9 --- /dev/null +++ b/src/test/ui/structs-enums/class-typarams.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/structs-enums/classes-cross-crate.rs b/src/test/ui/structs-enums/classes-cross-crate.rs new file mode 100644 index 00000000000..ca362c7a7d8 --- /dev/null +++ b/src/test/ui/structs-enums/classes-cross-crate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/structs-enums/classes-self-referential.rs b/src/test/ui/structs-enums/classes-self-referential.rs new file mode 100644 index 00000000000..27d6ebf2c2a --- /dev/null +++ b/src/test/ui/structs-enums/classes-self-referential.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/structs-enums/classes-simple-cross-crate.rs b/src/test/ui/structs-enums/classes-simple-cross-crate.rs new file mode 100644 index 00000000000..6ff0970c0f0 --- /dev/null +++ b/src/test/ui/structs-enums/classes-simple-cross-crate.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/classes-simple-method.rs b/src/test/ui/structs-enums/classes-simple-method.rs new file mode 100644 index 00000000000..f3d98337dba --- /dev/null +++ b/src/test/ui/structs-enums/classes-simple-method.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/structs-enums/classes-simple.rs b/src/test/ui/structs-enums/classes-simple.rs new file mode 100644 index 00000000000..568fbb29f0d --- /dev/null +++ b/src/test/ui/structs-enums/classes-simple.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/structs-enums/classes.rs b/src/test/ui/structs-enums/classes.rs new file mode 100644 index 00000000000..51d84b9091d --- /dev/null +++ b/src/test/ui/structs-enums/classes.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/structs-enums/codegen-tag-static-padding.rs b/src/test/ui/structs-enums/codegen-tag-static-padding.rs new file mode 100644 index 00000000000..8aa087c018b --- /dev/null +++ b/src/test/ui/structs-enums/codegen-tag-static-padding.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/structs-enums/compare-generic-enums.rs b/src/test/ui/structs-enums/compare-generic-enums.rs new file mode 100644 index 00000000000..84f953b1f8e --- /dev/null +++ b/src/test/ui/structs-enums/compare-generic-enums.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/structs-enums/discrim-explicit-23030.rs b/src/test/ui/structs-enums/discrim-explicit-23030.rs new file mode 100644 index 00000000000..211ca7e4e8f --- /dev/null +++ b/src/test/ui/structs-enums/discrim-explicit-23030.rs @@ -0,0 +1,147 @@ +// 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/src/test/ui/structs-enums/empty-struct-braces.rs b/src/test/ui/structs-enums/empty-struct-braces.rs new file mode 100644 index 00000000000..0663687c958 --- /dev/null +++ b/src/test/ui/structs-enums/empty-struct-braces.rs @@ -0,0 +1,213 @@ +// 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/src/test/ui/structs-enums/empty-tag.rs b/src/test/ui/structs-enums/empty-tag.rs new file mode 100644 index 00000000000..56a438200c0 --- /dev/null +++ b/src/test/ui/structs-enums/empty-tag.rs @@ -0,0 +1,21 @@ +// run-pass +#![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/src/test/ui/structs-enums/enum-alignment.rs b/src/test/ui/structs-enums/enum-alignment.rs new file mode 100644 index 00000000000..108dfe2e62d --- /dev/null +++ b/src/test/ui/structs-enums/enum-alignment.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/structs-enums/enum-clike-ffi-as-int.rs b/src/test/ui/structs-enums/enum-clike-ffi-as-int.rs new file mode 100644 index 00000000000..e2b2b43dee3 --- /dev/null +++ b/src/test/ui/structs-enums/enum-clike-ffi-as-int.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/structs-enums/enum-discr.rs b/src/test/ui/structs-enums/enum-discr.rs new file mode 100644 index 00000000000..bdd6df82d0f --- /dev/null +++ b/src/test/ui/structs-enums/enum-discr.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/structs-enums/enum-discrim-autosizing.rs b/src/test/ui/structs-enums/enum-discrim-autosizing.rs new file mode 100644 index 00000000000..f68fdda6053 --- /dev/null +++ b/src/test/ui/structs-enums/enum-discrim-autosizing.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/structs-enums/enum-discrim-manual-sizing.rs b/src/test/ui/structs-enums/enum-discrim-manual-sizing.rs new file mode 100644 index 00000000000..c8b362c9917 --- /dev/null +++ b/src/test/ui/structs-enums/enum-discrim-manual-sizing.rs @@ -0,0 +1,111 @@ +// 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/src/test/ui/structs-enums/enum-discrim-range-overflow.rs b/src/test/ui/structs-enums/enum-discrim-range-overflow.rs new file mode 100644 index 00000000000..9c4c61e684b --- /dev/null +++ b/src/test/ui/structs-enums/enum-discrim-range-overflow.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/structs-enums/enum-discrim-width-stuff.rs b/src/test/ui/structs-enums/enum-discrim-width-stuff.rs new file mode 100644 index 00000000000..f278ae2d0a8 --- /dev/null +++ b/src/test/ui/structs-enums/enum-discrim-width-stuff.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/structs-enums/enum-disr-val-pretty.rs b/src/test/ui/structs-enums/enum-disr-val-pretty.rs new file mode 100644 index 00000000000..ef1333e0eeb --- /dev/null +++ b/src/test/ui/structs-enums/enum-disr-val-pretty.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/structs-enums/enum-export-inheritance.rs b/src/test/ui/structs-enums/enum-export-inheritance.rs new file mode 100644 index 00000000000..6a36a004a7c --- /dev/null +++ b/src/test/ui/structs-enums/enum-export-inheritance.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/structs-enums/enum-layout-optimization.rs b/src/test/ui/structs-enums/enum-layout-optimization.rs new file mode 100644 index 00000000000..05d297906c3 --- /dev/null +++ b/src/test/ui/structs-enums/enum-layout-optimization.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs new file mode 100644 index 00000000000..78d8e5e3a5d --- /dev/null +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs @@ -0,0 +1,171 @@ +// 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. + #[allow(deprecated)] + let mut dest: MyEnum = mem::uninitialized(); + 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/src/test/ui/structs-enums/enum-non-c-like-repr-c.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-c.rs new file mode 100644 index 00000000000..1209533efda --- /dev/null +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-c.rs @@ -0,0 +1,171 @@ +// 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. + #[allow(deprecated)] + let mut dest: MyEnum = mem::uninitialized(); + 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/src/test/ui/structs-enums/enum-non-c-like-repr-int.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-int.rs new file mode 100644 index 00000000000..5dd9c1863d6 --- /dev/null +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-int.rs @@ -0,0 +1,167 @@ +// 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. + #[allow(deprecated)] + let mut dest: MyEnum = mem::uninitialized(); + 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/src/test/ui/structs-enums/enum-null-pointer-opt.rs b/src/test/ui/structs-enums/enum-null-pointer-opt.rs new file mode 100644 index 00000000000..32fdbf620a9 --- /dev/null +++ b/src/test/ui/structs-enums/enum-null-pointer-opt.rs @@ -0,0 +1,74 @@ +// 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/src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs b/src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs new file mode 100644 index 00000000000..ae267e7988e --- /dev/null +++ b/src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs b/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs new file mode 100644 index 00000000000..77419e1132d --- /dev/null +++ b/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/structs-enums/enum-univariant-repr.rs b/src/test/ui/structs-enums/enum-univariant-repr.rs new file mode 100644 index 00000000000..1e0f6788778 --- /dev/null +++ b/src/test/ui/structs-enums/enum-univariant-repr.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/structs-enums/enum-variants.rs b/src/test/ui/structs-enums/enum-variants.rs new file mode 100644 index 00000000000..9ac5aae726a --- /dev/null +++ b/src/test/ui/structs-enums/enum-variants.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/structs-enums/enum-vec-initializer.rs b/src/test/ui/structs-enums/enum-vec-initializer.rs new file mode 100644 index 00000000000..42ee8ba971e --- /dev/null +++ b/src/test/ui/structs-enums/enum-vec-initializer.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/structs-enums/export-abstract-tag.rs b/src/test/ui/structs-enums/export-abstract-tag.rs new file mode 100644 index 00000000000..76ac73321d3 --- /dev/null +++ b/src/test/ui/structs-enums/export-abstract-tag.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/structs-enums/export-tag-variant.rs b/src/test/ui/structs-enums/export-tag-variant.rs new file mode 100644 index 00000000000..52e0aba0979 --- /dev/null +++ b/src/test/ui/structs-enums/export-tag-variant.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/structs-enums/expr-if-struct.rs b/src/test/ui/structs-enums/expr-if-struct.rs new file mode 100644 index 00000000000..e62d47c6f5d --- /dev/null +++ b/src/test/ui/structs-enums/expr-if-struct.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/structs-enums/expr-match-struct.rs b/src/test/ui/structs-enums/expr-match-struct.rs new file mode 100644 index 00000000000..f0e8d897274 --- /dev/null +++ b/src/test/ui/structs-enums/expr-match-struct.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/structs-enums/field-destruction-order.rs b/src/test/ui/structs-enums/field-destruction-order.rs new file mode 100644 index 00000000000..a75a742d90f --- /dev/null +++ b/src/test/ui/structs-enums/field-destruction-order.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/structs-enums/foreign-struct.rs b/src/test/ui/structs-enums/foreign-struct.rs new file mode 100644 index 00000000000..ce02c8fb5c3 --- /dev/null +++ b/src/test/ui/structs-enums/foreign-struct.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/structs-enums/functional-struct-upd.rs b/src/test/ui/structs-enums/functional-struct-upd.rs new file mode 100644 index 00000000000..51c6b6d7e4f --- /dev/null +++ b/src/test/ui/structs-enums/functional-struct-upd.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/ivec-tag.rs b/src/test/ui/structs-enums/ivec-tag.rs new file mode 100644 index 00000000000..c39368a2bb8 --- /dev/null +++ b/src/test/ui/structs-enums/ivec-tag.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/structs-enums/module-qualified-struct-destructure.rs b/src/test/ui/structs-enums/module-qualified-struct-destructure.rs new file mode 100644 index 00000000000..57be37cdf2b --- /dev/null +++ b/src/test/ui/structs-enums/module-qualified-struct-destructure.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs b/src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs new file mode 100644 index 00000000000..30cf645821d --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs b/src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs new file mode 100644 index 00000000000..f6c395059ed --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs b/src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs new file mode 100644 index 00000000000..d2ccadea007 --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/structs-enums/namespaced-enum-glob-import.rs b/src/test/ui/structs-enums/namespaced-enum-glob-import.rs new file mode 100644 index 00000000000..f36ac69dc08 --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enum-glob-import.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/structs-enums/namespaced-enums-xcrate.rs b/src/test/ui/structs-enums/namespaced-enums-xcrate.rs new file mode 100644 index 00000000000..5e10c3ec1d0 --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enums-xcrate.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/structs-enums/namespaced-enums.rs b/src/test/ui/structs-enums/namespaced-enums.rs new file mode 100644 index 00000000000..6a2602501a5 --- /dev/null +++ b/src/test/ui/structs-enums/namespaced-enums.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/structs-enums/nested-enum-same-names.rs b/src/test/ui/structs-enums/nested-enum-same-names.rs new file mode 100644 index 00000000000..dece3dcd54b --- /dev/null +++ b/src/test/ui/structs-enums/nested-enum-same-names.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/structs-enums/newtype-struct-drop-run.rs b/src/test/ui/structs-enums/newtype-struct-drop-run.rs new file mode 100644 index 00000000000..0754f318701 --- /dev/null +++ b/src/test/ui/structs-enums/newtype-struct-drop-run.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/structs-enums/newtype-struct-with-dtor.rs b/src/test/ui/structs-enums/newtype-struct-with-dtor.rs new file mode 100644 index 00000000000..f73b492dfcf --- /dev/null +++ b/src/test/ui/structs-enums/newtype-struct-with-dtor.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/structs-enums/newtype-struct-xc-2.rs b/src/test/ui/structs-enums/newtype-struct-xc-2.rs new file mode 100644 index 00000000000..40837321be2 --- /dev/null +++ b/src/test/ui/structs-enums/newtype-struct-xc-2.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/structs-enums/newtype-struct-xc.rs b/src/test/ui/structs-enums/newtype-struct-xc.rs new file mode 100644 index 00000000000..0c6466d97fc --- /dev/null +++ b/src/test/ui/structs-enums/newtype-struct-xc.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/structs-enums/nonzero-enum.rs b/src/test/ui/structs-enums/nonzero-enum.rs new file mode 100644 index 00000000000..15b571be563 --- /dev/null +++ b/src/test/ui/structs-enums/nonzero-enum.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/structs-enums/numeric-fields.rs b/src/test/ui/structs-enums/numeric-fields.rs new file mode 100644 index 00000000000..6ff3afc3870 --- /dev/null +++ b/src/test/ui/structs-enums/numeric-fields.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs b/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs new file mode 100644 index 00000000000..e1a865fa503 --- /dev/null +++ b/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs @@ -0,0 +1,58 @@ +// 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/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs b/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs new file mode 100644 index 00000000000..1fc52ead48e --- /dev/null +++ b/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/structs-enums/rec-align-u32.rs b/src/test/ui/structs-enums/rec-align-u32.rs new file mode 100644 index 00000000000..889294daa34 --- /dev/null +++ b/src/test/ui/structs-enums/rec-align-u32.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs new file mode 100644 index 00000000000..c4e9e9ea5ee --- /dev/null +++ b/src/test/ui/structs-enums/rec-align-u64.rs @@ -0,0 +1,101 @@ +// 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"))] +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 { + #[cfg(target_arch = "x86")] + pub mod m { + pub fn align() -> usize { 8 } + pub fn size() -> usize { 16 } + } + + #[cfg(target_arch = "x86_64")] + 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/src/test/ui/structs-enums/rec-auto.rs b/src/test/ui/structs-enums/rec-auto.rs new file mode 100644 index 00000000000..c2ef13ede4c --- /dev/null +++ b/src/test/ui/structs-enums/rec-auto.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/structs-enums/rec-extend.rs b/src/test/ui/structs-enums/rec-extend.rs new file mode 100644 index 00000000000..4c91cd1850e --- /dev/null +++ b/src/test/ui/structs-enums/rec-extend.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/structs-enums/rec-tup.rs b/src/test/ui/structs-enums/rec-tup.rs new file mode 100644 index 00000000000..b85d28fdf03 --- /dev/null +++ b/src/test/ui/structs-enums/rec-tup.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/structs-enums/rec.rs b/src/test/ui/structs-enums/rec.rs new file mode 100644 index 00000000000..82c84ebd6ff --- /dev/null +++ b/src/test/ui/structs-enums/rec.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/structs-enums/record-pat.rs b/src/test/ui/structs-enums/record-pat.rs new file mode 100644 index 00000000000..1acaf2a32c2 --- /dev/null +++ b/src/test/ui/structs-enums/record-pat.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/structs-enums/resource-in-struct.rs b/src/test/ui/structs-enums/resource-in-struct.rs new file mode 100644 index 00000000000..35a4b14bc3f --- /dev/null +++ b/src/test/ui/structs-enums/resource-in-struct.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/structs-enums/simple-generic-tag.rs b/src/test/ui/structs-enums/simple-generic-tag.rs new file mode 100644 index 00000000000..dbd2834d468 --- /dev/null +++ b/src/test/ui/structs-enums/simple-generic-tag.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + + +// pretty-expanded FIXME #23616 + +enum clam { a(T), } + +pub fn main() { } diff --git a/src/test/ui/structs-enums/simple-match-generic-tag.rs b/src/test/ui/structs-enums/simple-match-generic-tag.rs new file mode 100644 index 00000000000..762fd49ad24 --- /dev/null +++ b/src/test/ui/structs-enums/simple-match-generic-tag.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/structs-enums/small-enum-range-edge.rs b/src/test/ui/structs-enums/small-enum-range-edge.rs new file mode 100644 index 00000000000..30612947963 --- /dev/null +++ b/src/test/ui/structs-enums/small-enum-range-edge.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/structs-enums/small-enums-with-fields.rs b/src/test/ui/structs-enums/small-enums-with-fields.rs new file mode 100644 index 00000000000..565ec1bd45d --- /dev/null +++ b/src/test/ui/structs-enums/small-enums-with-fields.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/structs-enums/struct-aliases-xcrate.rs b/src/test/ui/structs-enums/struct-aliases-xcrate.rs new file mode 100644 index 00000000000..ffe7b22f809 --- /dev/null +++ b/src/test/ui/structs-enums/struct-aliases-xcrate.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/structs-enums/struct-aliases.rs b/src/test/ui/structs-enums/struct-aliases.rs new file mode 100644 index 00000000000..b7aeed7bc39 --- /dev/null +++ b/src/test/ui/structs-enums/struct-aliases.rs @@ -0,0 +1,64 @@ +// 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/src/test/ui/structs-enums/struct-destructuring-cross-crate.rs b/src/test/ui/structs-enums/struct-destructuring-cross-crate.rs new file mode 100644 index 00000000000..19e0a0bbdd2 --- /dev/null +++ b/src/test/ui/structs-enums/struct-destructuring-cross-crate.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/struct-field-shorthand.rs b/src/test/ui/structs-enums/struct-field-shorthand.rs new file mode 100644 index 00000000000..ed650c68364 --- /dev/null +++ b/src/test/ui/structs-enums/struct-field-shorthand.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/structs-enums/struct-like-variant-construct.rs b/src/test/ui/structs-enums/struct-like-variant-construct.rs new file mode 100644 index 00000000000..60fc7ce394c --- /dev/null +++ b/src/test/ui/structs-enums/struct-like-variant-construct.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/structs-enums/struct-like-variant-match.rs b/src/test/ui/structs-enums/struct-like-variant-match.rs new file mode 100644 index 00000000000..ade1a697037 --- /dev/null +++ b/src/test/ui/structs-enums/struct-like-variant-match.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/structs-enums/struct-lit-functional-no-fields.rs b/src/test/ui/structs-enums/struct-lit-functional-no-fields.rs new file mode 100644 index 00000000000..f19604e951c --- /dev/null +++ b/src/test/ui/structs-enums/struct-lit-functional-no-fields.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/structs-enums/struct-literal-dtor.rs b/src/test/ui/structs-enums/struct-literal-dtor.rs new file mode 100644 index 00000000000..6d1b1dfb9b6 --- /dev/null +++ b/src/test/ui/structs-enums/struct-literal-dtor.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/structs-enums/struct-new-as-field-name.rs b/src/test/ui/structs-enums/struct-new-as-field-name.rs new file mode 100644 index 00000000000..641fc3c5867 --- /dev/null +++ b/src/test/ui/structs-enums/struct-new-as-field-name.rs @@ -0,0 +1,10 @@ +// run-pass + +struct Foo { + new: isize, +} + +pub fn main() { + let foo = Foo{ new: 3 }; + assert_eq!(foo.new, 3); +} diff --git a/src/test/ui/structs-enums/struct-order-of-eval-1.rs b/src/test/ui/structs-enums/struct-order-of-eval-1.rs new file mode 100644 index 00000000000..f3fe9953856 --- /dev/null +++ b/src/test/ui/structs-enums/struct-order-of-eval-1.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/structs-enums/struct-order-of-eval-2.rs b/src/test/ui/structs-enums/struct-order-of-eval-2.rs new file mode 100644 index 00000000000..a4e0edc97c6 --- /dev/null +++ b/src/test/ui/structs-enums/struct-order-of-eval-2.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/structs-enums/struct-order-of-eval-3.rs b/src/test/ui/structs-enums/struct-order-of-eval-3.rs new file mode 100644 index 00000000000..60887f8d05a --- /dev/null +++ b/src/test/ui/structs-enums/struct-order-of-eval-3.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/structs-enums/struct-order-of-eval-4.rs b/src/test/ui/structs-enums/struct-order-of-eval-4.rs new file mode 100644 index 00000000000..547df631846 --- /dev/null +++ b/src/test/ui/structs-enums/struct-order-of-eval-4.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/structs-enums/struct-partial-move-1.rs b/src/test/ui/structs-enums/struct-partial-move-1.rs new file mode 100644 index 00000000000..c1570159388 --- /dev/null +++ b/src/test/ui/structs-enums/struct-partial-move-1.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/structs-enums/struct-partial-move-2.rs b/src/test/ui/structs-enums/struct-partial-move-2.rs new file mode 100644 index 00000000000..4315e5c29f3 --- /dev/null +++ b/src/test/ui/structs-enums/struct-partial-move-2.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/structs-enums/struct-path-associated-type.rs b/src/test/ui/structs-enums/struct-path-associated-type.rs new file mode 100644 index 00000000000..2235dfe4b84 --- /dev/null +++ b/src/test/ui/structs-enums/struct-path-associated-type.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/structs-enums/struct-path-self.rs b/src/test/ui/structs-enums/struct-path-self.rs new file mode 100644 index 00000000000..e7a59858f57 --- /dev/null +++ b/src/test/ui/structs-enums/struct-path-self.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/structs-enums/struct-pattern-matching.rs b/src/test/ui/structs-enums/struct-pattern-matching.rs new file mode 100644 index 00000000000..89361bf2455 --- /dev/null +++ b/src/test/ui/structs-enums/struct-pattern-matching.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/structs-enums/struct-return.rs b/src/test/ui/structs-enums/struct-return.rs new file mode 100644 index 00000000000..5930fc4acbb --- /dev/null +++ b/src/test/ui/structs-enums/struct-return.rs @@ -0,0 +1,64 @@ +// 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 } + +mod rustrt { + use super::{Floats, Quad}; + + #[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; + } +} + +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() { +} + +pub fn main() { + test1(); + test2(); +} diff --git a/src/test/ui/structs-enums/struct-variant-field-visibility.rs b/src/test/ui/structs-enums/struct-variant-field-visibility.rs new file mode 100644 index 00000000000..7896c829a6e --- /dev/null +++ b/src/test/ui/structs-enums/struct-variant-field-visibility.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/structs-enums/struct_variant_xc.rs b/src/test/ui/structs-enums/struct_variant_xc.rs new file mode 100644 index 00000000000..9c8d1a69a3e --- /dev/null +++ b/src/test/ui/structs-enums/struct_variant_xc.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/structs-enums/struct_variant_xc_match.rs b/src/test/ui/structs-enums/struct_variant_xc_match.rs new file mode 100644 index 00000000000..5358d13faa9 --- /dev/null +++ b/src/test/ui/structs-enums/struct_variant_xc_match.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/structs-enums/tag-align-dyn-u64.rs b/src/test/ui/structs-enums/tag-align-dyn-u64.rs new file mode 100644 index 00000000000..3f7a5e3e511 --- /dev/null +++ b/src/test/ui/structs-enums/tag-align-dyn-u64.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/structs-enums/tag-align-dyn-variants.rs b/src/test/ui/structs-enums/tag-align-dyn-variants.rs new file mode 100644 index 00000000000..4d075b04c97 --- /dev/null +++ b/src/test/ui/structs-enums/tag-align-dyn-variants.rs @@ -0,0 +1,67 @@ +// 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/src/test/ui/structs-enums/tag-align-shape.rs b/src/test/ui/structs-enums/tag-align-shape.rs new file mode 100644 index 00000000000..87282ddbcca --- /dev/null +++ b/src/test/ui/structs-enums/tag-align-shape.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/structs-enums/tag-align-u64.rs b/src/test/ui/structs-enums/tag-align-u64.rs new file mode 100644 index 00000000000..684b27cd030 --- /dev/null +++ b/src/test/ui/structs-enums/tag-align-u64.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/structs-enums/tag-disr-val-shape.rs b/src/test/ui/structs-enums/tag-disr-val-shape.rs new file mode 100644 index 00000000000..51052626c30 --- /dev/null +++ b/src/test/ui/structs-enums/tag-disr-val-shape.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/structs-enums/tag-exports.rs b/src/test/ui/structs-enums/tag-exports.rs new file mode 100644 index 00000000000..1bcb7d35da3 --- /dev/null +++ b/src/test/ui/structs-enums/tag-exports.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/structs-enums/tag-in-block.rs b/src/test/ui/structs-enums/tag-in-block.rs new file mode 100644 index 00000000000..03d4dd9b0ab --- /dev/null +++ b/src/test/ui/structs-enums/tag-in-block.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs b/src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs new file mode 100644 index 00000000000..3f59db38310 --- /dev/null +++ b/src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/tag-variant-disr-val.rs b/src/test/ui/structs-enums/tag-variant-disr-val.rs new file mode 100644 index 00000000000..297d85c5886 --- /dev/null +++ b/src/test/ui/structs-enums/tag-variant-disr-val.rs @@ -0,0 +1,66 @@ +// 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/src/test/ui/structs-enums/tag.rs b/src/test/ui/structs-enums/tag.rs new file mode 100644 index 00000000000..5fcd64b7cd1 --- /dev/null +++ b/src/test/ui/structs-enums/tag.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/structs-enums/tuple-struct-construct.rs b/src/test/ui/structs-enums/tuple-struct-construct.rs new file mode 100644 index 00000000000..972fc9dc04a --- /dev/null +++ b/src/test/ui/structs-enums/tuple-struct-construct.rs @@ -0,0 +1,8 @@ +// run-pass +#[derive(Debug)] +struct Foo(isize, isize); + +pub fn main() { + let x = Foo(1, 2); + println!("{:?}", x); +} diff --git a/src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs b/src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs new file mode 100644 index 00000000000..23f06516323 --- /dev/null +++ b/src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/structs-enums/tuple-struct-destructuring.rs b/src/test/ui/structs-enums/tuple-struct-destructuring.rs new file mode 100644 index 00000000000..dff87ead033 --- /dev/null +++ b/src/test/ui/structs-enums/tuple-struct-destructuring.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/structs-enums/tuple-struct-matching.rs b/src/test/ui/structs-enums/tuple-struct-matching.rs new file mode 100644 index 00000000000..432be1d1f7a --- /dev/null +++ b/src/test/ui/structs-enums/tuple-struct-matching.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/structs-enums/tuple-struct-trivial.rs b/src/test/ui/structs-enums/tuple-struct-trivial.rs new file mode 100644 index 00000000000..c8651fd29de --- /dev/null +++ b/src/test/ui/structs-enums/tuple-struct-trivial.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Foo(isize, isize, isize); + +pub fn main() { +} diff --git a/src/test/ui/structs-enums/uninstantiable-struct.rs b/src/test/ui/structs-enums/uninstantiable-struct.rs new file mode 100644 index 00000000000..b1ef525614e --- /dev/null +++ b/src/test/ui/structs-enums/uninstantiable-struct.rs @@ -0,0 +1,4 @@ +// run-pass +pub struct Z(&'static Z); + +pub fn main() {} diff --git a/src/test/ui/structs-enums/unit-like-struct-drop-run.rs b/src/test/ui/structs-enums/unit-like-struct-drop-run.rs new file mode 100644 index 00000000000..980fd97e2c6 --- /dev/null +++ b/src/test/ui/structs-enums/unit-like-struct-drop-run.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/structs-enums/unit-like-struct.rs b/src/test/ui/structs-enums/unit-like-struct.rs new file mode 100644 index 00000000000..636ec992667 --- /dev/null +++ b/src/test/ui/structs-enums/unit-like-struct.rs @@ -0,0 +1,9 @@ +// run-pass +struct Foo; + +pub fn main() { + let x: Foo = Foo; + match x { + Foo => { println!("hi"); } + } +} diff --git a/src/test/ui/structs-enums/variant-structs-trivial.rs b/src/test/ui/structs-enums/variant-structs-trivial.rs new file mode 100644 index 00000000000..31fa610a69d --- /dev/null +++ b/src/test/ui/structs-enums/variant-structs-trivial.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Foo { + Bar { x: isize }, + Baz { y: isize } +} + +pub fn main() { } diff --git a/src/test/ui/structured-compare.rs b/src/test/ui/structured-compare.rs new file mode 100644 index 00000000000..63d30c4da89 --- /dev/null +++ b/src/test/ui/structured-compare.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/super-fast-paren-parsing.rs b/src/test/ui/super-fast-paren-parsing.rs new file mode 100644 index 00000000000..60c8db53a8c --- /dev/null +++ b/src/test/ui/super-fast-paren-parsing.rs @@ -0,0 +1,24 @@ +// run-pass + +#![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/src/test/ui/super.rs b/src/test/ui/super.rs new file mode 100644 index 00000000000..86c720288c3 --- /dev/null +++ b/src/test/ui/super.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/supported-cast.rs b/src/test/ui/supported-cast.rs new file mode 100644 index 00000000000..ff41ce6c79a --- /dev/null +++ b/src/test/ui/supported-cast.rs @@ -0,0 +1,206 @@ +// 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/src/test/ui/svh-add-nothing.rs b/src/test/ui/svh-add-nothing.rs new file mode 100644 index 00000000000..d7d037f0b32 --- /dev/null +++ b/src/test/ui/svh-add-nothing.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/swap-1.rs b/src/test/ui/swap-1.rs new file mode 100644 index 00000000000..d87114748dd --- /dev/null +++ b/src/test/ui/swap-1.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/swap-2.rs b/src/test/ui/swap-2.rs new file mode 100644 index 00000000000..c8f298ec0e5 --- /dev/null +++ b/src/test/ui/swap-2.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::mem::swap; + +pub fn main() { + let mut a: Vec = vec![0, 1, 2, 3, 4, 5, 6]; + a.swap(2, 4); + assert_eq!(a[2], 4); + assert_eq!(a[4], 2); + let mut n = 42; + swap(&mut n, &mut a[0]); + assert_eq!(a[0], 42); + assert_eq!(n, 0); +} diff --git a/src/test/ui/swap-overlapping.rs b/src/test/ui/swap-overlapping.rs new file mode 100644 index 00000000000..85b357e0c02 --- /dev/null +++ b/src/test/ui/swap-overlapping.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/tail-call-arg-leak.rs b/src/test/ui/tail-call-arg-leak.rs new file mode 100644 index 00000000000..a60944b632d --- /dev/null +++ b/src/test/ui/tail-call-arg-leak.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/tail-cps.rs b/src/test/ui/tail-cps.rs new file mode 100644 index 00000000000..f186683ea66 --- /dev/null +++ b/src/test/ui/tail-cps.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/tail-direct.rs b/src/test/ui/tail-direct.rs new file mode 100644 index 00000000000..c67c5b7a555 --- /dev/null +++ b/src/test/ui/tail-direct.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/tcp-stress.rs b/src/test/ui/tcp-stress.rs new file mode 100644 index 00000000000..1f1948fa8fa --- /dev/null +++ b/src/test/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) +// ignore-sgx no thread sleep support + +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/src/test/ui/terminate-in-initializer.rs b/src/test/ui/terminate-in-initializer.rs new file mode 100644 index 00000000000..c9cb932e62a --- /dev/null +++ b/src/test/ui/terminate-in-initializer.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/test-allow-dead-extern-static-no-warning.rs b/src/test/ui/test-allow-dead-extern-static-no-warning.rs new file mode 100644 index 00000000000..2583e431ec1 --- /dev/null +++ b/src/test/ui/test-allow-dead-extern-static-no-warning.rs @@ -0,0 +1,11 @@ +// run-pass +// compile-flags: --test + +#![deny(dead_code)] + +extern "C" { + #[allow(dead_code)] + static Qt: u64; +} + +fn main() {} diff --git a/src/test/ui/test-allow-fail-attr.rs b/src/test/ui/test-allow-fail-attr.rs new file mode 100644 index 00000000000..1a478460efc --- /dev/null +++ b/src/test/ui/test-allow-fail-attr.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: --test +#![feature(allow_fail)] + +#[test] +#[allow_fail] +fn test1() { + panic!(); +} + +#[test] +#[allow_fail] +fn test2() { + assert!(true); +} diff --git a/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs new file mode 100644 index 00000000000..ff62d84925f --- /dev/null +++ b/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/test-main-not-dead-attr.rs b/src/test/ui/test-main-not-dead-attr.rs new file mode 100644 index 00000000000..628b1896ace --- /dev/null +++ b/src/test/ui/test-main-not-dead-attr.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags: --test + +#![feature(main)] + +#![deny(dead_code)] + +#[main] +fn foo() { panic!(); } diff --git a/src/test/ui/test-main-not-dead.rs b/src/test/ui/test-main-not-dead.rs new file mode 100644 index 00000000000..30a9c85e3d2 --- /dev/null +++ b/src/test/ui/test-main-not-dead.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: --test + +#![deny(dead_code)] + +fn main() { panic!(); } diff --git a/src/test/ui/test-runner-hides-buried-main.rs b/src/test/ui/test-runner-hides-buried-main.rs new file mode 100644 index 00000000000..917c09801e1 --- /dev/null +++ b/src/test/ui/test-runner-hides-buried-main.rs @@ -0,0 +1,15 @@ +// run-pass +// compile-flags: --test + +#![feature(main)] + +#![allow(dead_code)] + +mod a { + fn b() { + || { + #[main] + fn c() { panic!(); } + }; + } +} diff --git a/src/test/ui/test-runner-hides-main.rs b/src/test/ui/test-runner-hides-main.rs new file mode 100644 index 00000000000..0de1d64f0fc --- /dev/null +++ b/src/test/ui/test-runner-hides-main.rs @@ -0,0 +1,5 @@ +// 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/src/test/ui/test-runner-hides-start.rs b/src/test/ui/test-runner-hides-start.rs new file mode 100644 index 00000000000..56212bb6f4b --- /dev/null +++ b/src/test/ui/test-runner-hides-start.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: --test + +#![feature(start)] + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { panic!(); } diff --git a/src/test/ui/test-should-fail-good-message.rs b/src/test/ui/test-should-fail-good-message.rs new file mode 100644 index 00000000000..9fa759f9eb4 --- /dev/null +++ b/src/test/ui/test-should-fail-good-message.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/test-vs-cfg-test.rs b/src/test/ui/test-vs-cfg-test.rs new file mode 100644 index 00000000000..cd1cd33c284 --- /dev/null +++ b/src/test/ui/test-vs-cfg-test.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags: --cfg test + +// Make sure `--cfg test` does not inject test harness + +#[test] +fn test() { panic!(); } + +fn main() {} diff --git a/src/test/ui/thin-lto-global-allocator.rs b/src/test/ui/thin-lto-global-allocator.rs new file mode 100644 index 00000000000..e00c5caf97c --- /dev/null +++ b/src/test/ui/thin-lto-global-allocator.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/thinlto/all-crates.rs b/src/test/ui/thinlto/all-crates.rs new file mode 100644 index 00000000000..e910b2a9f96 --- /dev/null +++ b/src/test/ui/thinlto/all-crates.rs @@ -0,0 +1,8 @@ +// run-pass + +// compile-flags: -Clto=thin +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} diff --git a/src/test/ui/thinlto/auxiliary/dylib.rs b/src/test/ui/thinlto/auxiliary/dylib.rs new file mode 100644 index 00000000000..e8b7f8f9f47 --- /dev/null +++ b/src/test/ui/thinlto/auxiliary/dylib.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z thinlto -C codegen-units=8 + +#[inline] +pub fn foo(b: u8) { + b.to_string(); +} diff --git a/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs b/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs new file mode 100644 index 00000000000..933af050a6a --- /dev/null +++ b/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs new file mode 100644 index 00000000000..5fd3f1996dd --- /dev/null +++ b/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn bar() -> u32 { + 3 +} diff --git a/src/test/ui/thinlto/dylib-works.rs b/src/test/ui/thinlto/dylib-works.rs new file mode 100644 index 00000000000..9e0782b590e --- /dev/null +++ b/src/test/ui/thinlto/dylib-works.rs @@ -0,0 +1,9 @@ +// run-pass + +// aux-build:dylib.rs + +extern crate dylib; + +fn main() { + dylib::foo(1); +} diff --git a/src/test/ui/thinlto/msvc-imp-present.rs b/src/test/ui/thinlto/msvc-imp-present.rs new file mode 100644 index 00000000000..5498afb2937 --- /dev/null +++ b/src/test/ui/thinlto/msvc-imp-present.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/thinlto/thin-lto-inlines.rs b/src/test/ui/thinlto/thin-lto-inlines.rs new file mode 100644 index 00000000000..dca7918077e --- /dev/null +++ b/src/test/ui/thinlto/thin-lto-inlines.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/thinlto/thin-lto-inlines2.rs b/src/test/ui/thinlto/thin-lto-inlines2.rs new file mode 100644 index 00000000000..1eb29657c70 --- /dev/null +++ b/src/test/ui/thinlto/thin-lto-inlines2.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/thinlto/weak-works.rs b/src/test/ui/thinlto/weak-works.rs new file mode 100644 index 00000000000..163a3870248 --- /dev/null +++ b/src/test/ui/thinlto/weak-works.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/thread-local-not-in-prelude.rs b/src/test/ui/thread-local-not-in-prelude.rs new file mode 100644 index 00000000000..03974982625 --- /dev/null +++ b/src/test/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/src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs b/src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs new file mode 100644 index 00000000000..b237b1c480e --- /dev/null +++ b/src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs @@ -0,0 +1,10 @@ +#![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/src/test/ui/threads-sendsync/comm.rs b/src/test/ui/threads-sendsync/comm.rs new file mode 100644 index 00000000000..aa86e174d44 --- /dev/null +++ b/src/test/ui/threads-sendsync/comm.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/threads-sendsync/send-is-not-static-par-for.rs b/src/test/ui/threads-sendsync/send-is-not-static-par-for.rs new file mode 100644 index 00000000000..dbe46555101 --- /dev/null +++ b/src/test/ui/threads-sendsync/send-is-not-static-par-for.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/threads-sendsync/send-resource.rs b/src/test/ui/threads-sendsync/send-resource.rs new file mode 100644 index 00000000000..023a84d6b6e --- /dev/null +++ b/src/test/ui/threads-sendsync/send-resource.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/threads-sendsync/send-type-inference.rs b/src/test/ui/threads-sendsync/send-type-inference.rs new file mode 100644 index 00000000000..0d9af7512b4 --- /dev/null +++ b/src/test/ui/threads-sendsync/send-type-inference.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/threads-sendsync/send_str_hashmap.rs b/src/test/ui/threads-sendsync/send_str_hashmap.rs new file mode 100644 index 00000000000..7d4cca8ad74 --- /dev/null +++ b/src/test/ui/threads-sendsync/send_str_hashmap.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/threads-sendsync/send_str_treemap.rs b/src/test/ui/threads-sendsync/send_str_treemap.rs new file mode 100644 index 00000000000..4d463174590 --- /dev/null +++ b/src/test/ui/threads-sendsync/send_str_treemap.rs @@ -0,0 +1,58 @@ +// 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/src/test/ui/threads-sendsync/sendable-class.rs b/src/test/ui/threads-sendsync/sendable-class.rs new file mode 100644 index 00000000000..7facf245bde --- /dev/null +++ b/src/test/ui/threads-sendsync/sendable-class.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/threads-sendsync/sendfn-is-a-block.rs b/src/test/ui/threads-sendsync/sendfn-is-a-block.rs new file mode 100644 index 00000000000..62807d8941a --- /dev/null +++ b/src/test/ui/threads-sendsync/sendfn-is-a-block.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs new file mode 100644 index 00000000000..8c40b2a5f11 --- /dev/null +++ b/src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/threads-sendsync/spawn-fn.rs b/src/test/ui/threads-sendsync/spawn-fn.rs new file mode 100644 index 00000000000..1243bb2579f --- /dev/null +++ b/src/test/ui/threads-sendsync/spawn-fn.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/threads-sendsync/spawn-types.rs b/src/test/ui/threads-sendsync/spawn-types.rs new file mode 100644 index 00000000000..1bead6e1bb1 --- /dev/null +++ b/src/test/ui/threads-sendsync/spawn-types.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/threads-sendsync/spawn.rs b/src/test/ui/threads-sendsync/spawn.rs new file mode 100644 index 00000000000..b1dcc9417fb --- /dev/null +++ b/src/test/ui/threads-sendsync/spawn.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/threads-sendsync/spawn2.rs b/src/test/ui/threads-sendsync/spawn2.rs new file mode 100644 index 00000000000..83e066aef96 --- /dev/null +++ b/src/test/ui/threads-sendsync/spawn2.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/threads-sendsync/spawning-with-debug.rs b/src/test/ui/threads-sendsync/spawning-with-debug.rs new file mode 100644 index 00000000000..388d62aa710 --- /dev/null +++ b/src/test/ui/threads-sendsync/spawning-with-debug.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-windows +// exec-env:RUSTC_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/src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs b/src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs new file mode 100644 index 00000000000..bc64c816243 --- /dev/null +++ b/src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/threads-sendsync/sync-send-atomics.rs b/src/test/ui/threads-sendsync/sync-send-atomics.rs new file mode 100644 index 00000000000..0466f4f0e9d --- /dev/null +++ b/src/test/ui/threads-sendsync/sync-send-atomics.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/threads-sendsync/sync-send-in-std.rs b/src/test/ui/threads-sendsync/sync-send-in-std.rs new file mode 100644 index 00000000000..15e10dc250f --- /dev/null +++ b/src/test/ui/threads-sendsync/sync-send-in-std.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs new file mode 100644 index 00000000000..fd53bb607f7 --- /dev/null +++ b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs @@ -0,0 +1,71 @@ +// 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/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs new file mode 100644 index 00000000000..44beb9dc1e5 --- /dev/null +++ b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs @@ -0,0 +1,104 @@ +// 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!(once(1)); + + // for option.rs + // FIXME + + // for result.rs + // FIXME + + // for slice.rs + // FIXME + + // for str/mod.rs + // FIXME +} diff --git a/src/test/ui/threads-sendsync/task-comm-0.rs b/src/test/ui/threads-sendsync/task-comm-0.rs new file mode 100644 index 00000000000..2b9a50e4d41 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-0.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/threads-sendsync/task-comm-1.rs b/src/test/ui/threads-sendsync/task-comm-1.rs new file mode 100644 index 00000000000..68ca62909bf --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-1.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/threads-sendsync/task-comm-10.rs b/src/test/ui/threads-sendsync/task-comm-10.rs new file mode 100644 index 00000000000..4cac0dc90cf --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-10.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/threads-sendsync/task-comm-11.rs b/src/test/ui/threads-sendsync/task-comm-11.rs new file mode 100644 index 00000000000..8541e143fb9 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-11.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/threads-sendsync/task-comm-12.rs b/src/test/ui/threads-sendsync/task-comm-12.rs new file mode 100644 index 00000000000..613a5cee58b --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-12.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/threads-sendsync/task-comm-13.rs b/src/test/ui/threads-sendsync/task-comm-13.rs new file mode 100644 index 00000000000..327eaaf8fa1 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-13.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/threads-sendsync/task-comm-14.rs b/src/test/ui/threads-sendsync/task-comm-14.rs new file mode 100644 index 00000000000..88d6b090268 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-14.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/threads-sendsync/task-comm-15.rs b/src/test/ui/threads-sendsync/task-comm-15.rs new file mode 100644 index 00000000000..adb14abdce9 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-15.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/threads-sendsync/task-comm-16.rs b/src/test/ui/threads-sendsync/task-comm-16.rs new file mode 100644 index 00000000000..d808fd9aceb --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-16.rs @@ -0,0 +1,111 @@ +// 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/src/test/ui/threads-sendsync/task-comm-17.rs b/src/test/ui/threads-sendsync/task-comm-17.rs new file mode 100644 index 00000000000..72249787093 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-17.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/threads-sendsync/task-comm-3.rs b/src/test/ui/threads-sendsync/task-comm-3.rs new file mode 100644 index 00000000000..570ae0a82ff --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-3.rs @@ -0,0 +1,63 @@ +// 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/src/test/ui/threads-sendsync/task-comm-4.rs b/src/test/ui/threads-sendsync/task-comm-4.rs new file mode 100644 index 00000000000..b259d69d15d --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-4.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/threads-sendsync/task-comm-5.rs b/src/test/ui/threads-sendsync/task-comm-5.rs new file mode 100644 index 00000000000..cdedf034ac3 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-5.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/threads-sendsync/task-comm-6.rs b/src/test/ui/threads-sendsync/task-comm-6.rs new file mode 100644 index 00000000000..990205ad334 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-6.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/threads-sendsync/task-comm-7.rs b/src/test/ui/threads-sendsync/task-comm-7.rs new file mode 100644 index 00000000000..0b9673e0033 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-7.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/threads-sendsync/task-comm-9.rs b/src/test/ui/threads-sendsync/task-comm-9.rs new file mode 100644 index 00000000000..5ed33012100 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-9.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/threads-sendsync/task-comm-chan-nil.rs b/src/test/ui/threads-sendsync/task-comm-chan-nil.rs new file mode 100644 index 00000000000..a93ddff43dc --- /dev/null +++ b/src/test/ui/threads-sendsync/task-comm-chan-nil.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/threads-sendsync/task-life-0.rs b/src/test/ui/threads-sendsync/task-life-0.rs new file mode 100644 index 00000000000..785cff9a0f3 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-life-0.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs b/src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs new file mode 100644 index 00000000000..458f5653885 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/threads-sendsync/task-stderr.rs b/src/test/ui/threads-sendsync/task-stderr.rs new file mode 100644 index 00000000000..d474084bf20 --- /dev/null +++ b/src/test/ui/threads-sendsync/task-stderr.rs @@ -0,0 +1,32 @@ +// 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(()) } +} + +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/src/test/ui/threads-sendsync/thread-local-extern-static.rs b/src/test/ui/threads-sendsync/thread-local-extern-static.rs new file mode 100644 index 00000000000..e10f5174b12 --- /dev/null +++ b/src/test/ui/threads-sendsync/thread-local-extern-static.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/threads-sendsync/thread-local-syntax.rs b/src/test/ui/threads-sendsync/thread-local-syntax.rs new file mode 100644 index 00000000000..2f4805e4731 --- /dev/null +++ b/src/test/ui/threads-sendsync/thread-local-syntax.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/threads-sendsync/threads.rs b/src/test/ui/threads-sendsync/threads.rs new file mode 100644 index 00000000000..e3da83aa12b --- /dev/null +++ b/src/test/ui/threads-sendsync/threads.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs new file mode 100644 index 00000000000..8baef433410 --- /dev/null +++ b/src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/threads-sendsync/tls-init-on-init.rs b/src/test/ui/threads-sendsync/tls-init-on-init.rs new file mode 100644 index 00000000000..193c1815105 --- /dev/null +++ b/src/test/ui/threads-sendsync/tls-init-on-init.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/threads-sendsync/tls-try-with.rs b/src/test/ui/threads-sendsync/tls-try-with.rs new file mode 100644 index 00000000000..f36ab4e4f9c --- /dev/null +++ b/src/test/ui/threads-sendsync/tls-try-with.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/tool_attributes.rs b/src/test/ui/tool_attributes.rs new file mode 100644 index 00000000000..be4a10c0ee9 --- /dev/null +++ b/src/test/ui/tool_attributes.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/tool_lints_2018_preview.rs b/src/test/ui/tool_lints_2018_preview.rs new file mode 100644 index 00000000000..190f0b99dc8 --- /dev/null +++ b/src/test/ui/tool_lints_2018_preview.rs @@ -0,0 +1,7 @@ +// run-pass + +#![feature(rust_2018_preview)] +#![deny(unknown_lints)] + +#[allow(clippy::almost_swapped)] +fn main() {} diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs new file mode 100644 index 00000000000..f34e6b7606d --- /dev/null +++ b/src/test/ui/trailing-comma.rs @@ -0,0 +1,37 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(slice_patterns)] + +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/src/test/ui/traits/anon-trait-static-method.rs b/src/test/ui/traits/anon-trait-static-method.rs new file mode 100644 index 00000000000..ede01afae02 --- /dev/null +++ b/src/test/ui/traits/anon-trait-static-method.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/traits/anon_trait_static_method_exe.rs b/src/test/ui/traits/anon_trait_static_method_exe.rs new file mode 100644 index 00000000000..b4930295499 --- /dev/null +++ b/src/test/ui/traits/anon_trait_static_method_exe.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/traits/assignability-trait.rs b/src/test/ui/traits/assignability-trait.rs new file mode 100644 index 00000000000..a8547c1d271 --- /dev/null +++ b/src/test/ui/traits/assignability-trait.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/traits/astconv-cycle-between-trait-and-type.rs b/src/test/ui/traits/astconv-cycle-between-trait-and-type.rs new file mode 100644 index 00000000000..cc8f9dc5190 --- /dev/null +++ b/src/test/ui/traits/astconv-cycle-between-trait-and-type.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/traits/augmented-assignments-trait.rs b/src/test/ui/traits/augmented-assignments-trait.rs new file mode 100644 index 00000000000..8c418daffdf --- /dev/null +++ b/src/test/ui/traits/augmented-assignments-trait.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/traits/auto-traits.rs b/src/test/ui/traits/auto-traits.rs new file mode 100644 index 00000000000..c495b97b25b --- /dev/null +++ b/src/test/ui/traits/auto-traits.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_doc_comments)] +#![feature(optin_builtin_traits)] + +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/src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs b/src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs new file mode 100644 index 00000000000..dceec7e3ec1 --- /dev/null +++ b/src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs @@ -0,0 +1,9 @@ +pub struct Foo { + pub x: isize +} + +impl Foo { + pub fn new() -> Foo { + Foo { x: 3 } + } +} diff --git a/src/test/ui/traits/auxiliary/go_trait.rs b/src/test/ui/traits/auxiliary/go_trait.rs new file mode 100644 index 00000000000..aa0ec22896d --- /dev/null +++ b/src/test/ui/traits/auxiliary/go_trait.rs @@ -0,0 +1,43 @@ +#![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/src/test/ui/traits/auxiliary/trait_alias.rs b/src/test/ui/traits/auxiliary/trait_alias.rs new file mode 100644 index 00000000000..9e412215512 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_alias.rs @@ -0,0 +1,13 @@ +#![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/src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs new file mode 100644 index 00000000000..0fb26af80c7 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs @@ -0,0 +1,40 @@ +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/src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs new file mode 100644 index 00000000000..15480132a23 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs new file mode 100644 index 00000000000..e9327676dc6 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs @@ -0,0 +1,9 @@ +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/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs new file mode 100644 index 00000000000..9af26cb2e2b --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs @@ -0,0 +1,7 @@ +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/src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs new file mode 100644 index 00000000000..a2570441226 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs @@ -0,0 +1,38 @@ +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/src/test/ui/traits/auxiliary/trait_xc_call_aux.rs b/src/test/ui/traits/auxiliary/trait_xc_call_aux.rs new file mode 100644 index 00000000000..b76c52e62a9 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_xc_call_aux.rs @@ -0,0 +1,11 @@ +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/src/test/ui/traits/auxiliary/traitimpl.rs b/src/test/ui/traits/auxiliary/traitimpl.rs new file mode 100644 index 00000000000..fda5314cdbf --- /dev/null +++ b/src/test/ui/traits/auxiliary/traitimpl.rs @@ -0,0 +1,7 @@ +// Test inherent trait impls work cross-crait. + +pub trait Bar<'a> : 'a {} + +impl<'a> Bar<'a> { + pub fn bar(&self) {} +} diff --git a/src/test/ui/traits/cycle-trait-type-trait.rs b/src/test/ui/traits/cycle-trait-type-trait.rs new file mode 100644 index 00000000000..c62d01403c7 --- /dev/null +++ b/src/test/ui/traits/cycle-trait-type-trait.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/traits/default-method-supertrait-vtable.rs b/src/test/ui/traits/default-method-supertrait-vtable.rs new file mode 100644 index 00000000000..939ad51355e --- /dev/null +++ b/src/test/ui/traits/default-method-supertrait-vtable.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/traits/dyn-trait.rs b/src/test/ui/traits/dyn-trait.rs new file mode 100644 index 00000000000..e1c1a8de55a --- /dev/null +++ b/src/test/ui/traits/dyn-trait.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/traits/fmt-pointer-trait.rs b/src/test/ui/traits/fmt-pointer-trait.rs new file mode 100644 index 00000000000..b7876b9bd51 --- /dev/null +++ b/src/test/ui/traits/fmt-pointer-trait.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/traits/impl-implicit-trait.rs b/src/test/ui/traits/impl-implicit-trait.rs new file mode 100644 index 00000000000..fac2bcce248 --- /dev/null +++ b/src/test/ui/traits/impl-implicit-trait.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/impl-inherent-prefer-over-trait.rs b/src/test/ui/traits/impl-inherent-prefer-over-trait.rs new file mode 100644 index 00000000000..82760788897 --- /dev/null +++ b/src/test/ui/traits/impl-inherent-prefer-over-trait.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/traits/infer-from-object-trait-issue-26952.rs b/src/test/ui/traits/infer-from-object-trait-issue-26952.rs new file mode 100644 index 00000000000..ed258dbb24c --- /dev/null +++ b/src/test/ui/traits/infer-from-object-trait-issue-26952.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/inherent-trait-method-order.rs b/src/test/ui/traits/inherent-trait-method-order.rs new file mode 100644 index 00000000000..f632ae8a9ac --- /dev/null +++ b/src/test/ui/traits/inherent-trait-method-order.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/traits/kindck-owned-trait-contains-1.rs b/src/test/ui/traits/kindck-owned-trait-contains-1.rs new file mode 100644 index 00000000000..23b91f924b5 --- /dev/null +++ b/src/test/ui/traits/kindck-owned-trait-contains-1.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/multiple-trait-bounds.rs b/src/test/ui/traits/multiple-trait-bounds.rs new file mode 100644 index 00000000000..868b334070b --- /dev/null +++ b/src/test/ui/traits/multiple-trait-bounds.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_: T) { +} + +pub fn main() { + f(3); +} diff --git a/src/test/ui/traits/object-one-type-two-traits.rs b/src/test/ui/traits/object-one-type-two-traits.rs new file mode 100644 index 00000000000..b92a2ab7b4b --- /dev/null +++ b/src/test/ui/traits/object-one-type-two-traits.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs new file mode 100644 index 00000000000..bc8dc8dbd05 --- /dev/null +++ b/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![feature(overlapping_marker_traits)] +#![feature(optin_builtin_traits)] + +// Overlapping negative impls for `MyStruct` are permitted: +struct MyStruct; +impl !Send for MyStruct {} +impl !Send for MyStruct {} + +fn main() { +} diff --git a/src/test/ui/traits/overlap-permitted-for-marker-traits.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs new file mode 100644 index 00000000000..59ec9d5689d --- /dev/null +++ b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs @@ -0,0 +1,27 @@ +// 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(overlapping_marker_traits)] +#![feature(optin_builtin_traits)] + +use std::fmt::{Debug, Display}; + +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/src/test/ui/traits/parameterized-trait-with-bounds.rs b/src/test/ui/traits/parameterized-trait-with-bounds.rs new file mode 100644 index 00000000000..832d4f6c89f --- /dev/null +++ b/src/test/ui/traits/parameterized-trait-with-bounds.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/traits/principal-less-trait-objects.rs b/src/test/ui/traits/principal-less-trait-objects.rs new file mode 100644 index 00000000000..82624650a54 --- /dev/null +++ b/src/test/ui/traits/principal-less-trait-objects.rs @@ -0,0 +1,42 @@ +// 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/src/test/ui/traits/supertrait-default-generics.rs b/src/test/ui/traits/supertrait-default-generics.rs new file mode 100644 index 00000000000..e862c0e976b --- /dev/null +++ b/src/test/ui/traits/supertrait-default-generics.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/traits/syntax-trait-polarity.rs b/src/test/ui/traits/syntax-trait-polarity.rs new file mode 100644 index 00000000000..c6524f5c8e7 --- /dev/null +++ b/src/test/ui/traits/syntax-trait-polarity.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(optin_builtin_traits)] + +struct TestType; + +impl TestType {} + +trait TestTrait {} + +impl !Send for TestType {} + +struct TestType2(T); + +impl TestType2 {} + +impl !Send for TestType2 {} + +fn main() {} diff --git a/src/test/ui/traits/trait-alias-import-cross-crate.rs b/src/test/ui/traits/trait-alias-import-cross-crate.rs new file mode 100644 index 00000000000..975542ab49b --- /dev/null +++ b/src/test/ui/traits/trait-alias-import-cross-crate.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/traits/trait-alias-import.rs b/src/test/ui/traits/trait-alias-import.rs new file mode 100644 index 00000000000..802a8f15698 --- /dev/null +++ b/src/test/ui/traits/trait-alias-import.rs @@ -0,0 +1,40 @@ +// 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/src/test/ui/traits/trait-bounds-basic.rs b/src/test/ui/traits/trait-bounds-basic.rs new file mode 100644 index 00000000000..8c8a7eb7d9d --- /dev/null +++ b/src/test/ui/traits/trait-bounds-basic.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs b/src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs new file mode 100644 index 00000000000..de6c2afa2bb --- /dev/null +++ b/src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/traits/trait-bounds-in-arc.rs b/src/test/ui/traits/trait-bounds-in-arc.rs new file mode 100644 index 00000000000..a45d834297e --- /dev/null +++ b/src/test/ui/traits/trait-bounds-in-arc.rs @@ -0,0 +1,109 @@ +// run-pass +#![allow(unused_must_use)] +// Tests that a heterogeneous list of existential 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/src/test/ui/traits/trait-bounds-recursion.rs b/src/test/ui/traits/trait-bounds-recursion.rs new file mode 100644 index 00000000000..0023ff654e8 --- /dev/null +++ b/src/test/ui/traits/trait-bounds-recursion.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/trait-bounds.rs b/src/test/ui/traits/trait-bounds.rs new file mode 100644 index 00000000000..18382bb59a4 --- /dev/null +++ b/src/test/ui/traits/trait-bounds.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/traits/trait-cache-issue-18209.rs b/src/test/ui/traits/trait-cache-issue-18209.rs new file mode 100644 index 00000000000..15676e4554a --- /dev/null +++ b/src/test/ui/traits/trait-cache-issue-18209.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/trait-coercion-generic.rs b/src/test/ui/traits/trait-coercion-generic.rs new file mode 100644 index 00000000000..bf4dda49519 --- /dev/null +++ b/src/test/ui/traits/trait-coercion-generic.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/traits/trait-coercion.rs b/src/test/ui/traits/trait-coercion.rs new file mode 100644 index 00000000000..cba33af1f1a --- /dev/null +++ b/src/test/ui/traits/trait-coercion.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/traits/trait-composition-trivial.rs b/src/test/ui/traits/trait-composition-trivial.rs new file mode 100644 index 00000000000..90e5dcd68e8 --- /dev/null +++ b/src/test/ui/traits/trait-composition-trivial.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + fn foo(&self); +} + +trait Bar : Foo { + fn bar(&self); +} + +pub fn main() {} diff --git a/src/test/ui/traits/trait-copy-guessing.rs b/src/test/ui/traits/trait-copy-guessing.rs new file mode 100644 index 00000000000..f031dd9ca48 --- /dev/null +++ b/src/test/ui/traits/trait-copy-guessing.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/traits/trait-default-method-bound-subst.rs b/src/test/ui/traits/trait-default-method-bound-subst.rs new file mode 100644 index 00000000000..6a5d5c8ba2d --- /dev/null +++ b/src/test/ui/traits/trait-default-method-bound-subst.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/traits/trait-default-method-bound-subst2.rs b/src/test/ui/traits/trait-default-method-bound-subst2.rs new file mode 100644 index 00000000000..78eabba2d23 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-bound-subst2.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/traits/trait-default-method-bound-subst3.rs b/src/test/ui/traits/trait-default-method-bound-subst3.rs new file mode 100644 index 00000000000..dd39dec4b63 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-bound-subst3.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/traits/trait-default-method-bound-subst4.rs b/src/test/ui/traits/trait-default-method-bound-subst4.rs new file mode 100644 index 00000000000..ef133064582 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-bound-subst4.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/traits/trait-default-method-bound.rs b/src/test/ui/traits/trait-default-method-bound.rs new file mode 100644 index 00000000000..0855a9db851 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-bound.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/traits/trait-default-method-xc-2.rs b/src/test/ui/traits/trait-default-method-xc-2.rs new file mode 100644 index 00000000000..5fa1a6cba72 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-xc-2.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/trait-default-method-xc.rs b/src/test/ui/traits/trait-default-method-xc.rs new file mode 100644 index 00000000000..3c20a649613 --- /dev/null +++ b/src/test/ui/traits/trait-default-method-xc.rs @@ -0,0 +1,81 @@ +// 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/src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs b/src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs new file mode 100644 index 00000000000..3413db6a684 --- /dev/null +++ b/src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/traits/trait-generic.rs b/src/test/ui/traits/trait-generic.rs new file mode 100644 index 00000000000..80efe1c9375 --- /dev/null +++ b/src/test/ui/traits/trait-generic.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/traits/trait-impl-2.rs b/src/test/ui/traits/trait-impl-2.rs new file mode 100644 index 00000000000..804ffec12c2 --- /dev/null +++ b/src/test/ui/traits/trait-impl-2.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/traits/trait-impl.rs b/src/test/ui/traits/trait-impl.rs new file mode 100644 index 00000000000..14796ce19c8 --- /dev/null +++ b/src/test/ui/traits/trait-impl.rs @@ -0,0 +1,41 @@ +// 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/src/test/ui/traits/trait-inheritance-auto-xc-2.rs b/src/test/ui/traits/trait-inheritance-auto-xc-2.rs new file mode 100644 index 00000000000..62c3ce8030c --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-auto-xc-2.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/trait-inheritance-auto-xc.rs b/src/test/ui/traits/trait-inheritance-auto-xc.rs new file mode 100644 index 00000000000..e8e651091ad --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-auto-xc.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/traits/trait-inheritance-auto.rs b/src/test/ui/traits/trait-inheritance-auto.rs new file mode 100644 index 00000000000..0be67a55eba --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-auto.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/traits/trait-inheritance-call-bound-inherited.rs b/src/test/ui/traits/trait-inheritance-call-bound-inherited.rs new file mode 100644 index 00000000000..37c2ff63c6a --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-call-bound-inherited.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 { 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/src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs b/src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs new file mode 100644 index 00000000000..8576d29f251 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs b/src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs new file mode 100644 index 00000000000..25159c1adb6 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/traits/trait-inheritance-cast.rs b/src/test/ui/traits/trait-inheritance-cast.rs new file mode 100644 index 00000000000..9070b9d1f56 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-cast.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs b/src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs new file mode 100644 index 00000000000..dbefb22cb72 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/trait-inheritance-cross-trait-call.rs b/src/test/ui/traits/trait-inheritance-cross-trait-call.rs new file mode 100644 index 00000000000..512c928ca8f --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-cross-trait-call.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/traits/trait-inheritance-diamond.rs b/src/test/ui/traits/trait-inheritance-diamond.rs new file mode 100644 index 00000000000..32ad0fb4d41 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-diamond.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/traits/trait-inheritance-multiple-inheritors.rs b/src/test/ui/traits/trait-inheritance-multiple-inheritors.rs new file mode 100644 index 00000000000..77ecbd8eb17 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-multiple-inheritors.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/trait-inheritance-multiple-params.rs b/src/test/ui/traits/trait-inheritance-multiple-params.rs new file mode 100644 index 00000000000..8ff5ba54185 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-multiple-params.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/trait-inheritance-num.rs b/src/test/ui/traits/trait-inheritance-num.rs new file mode 100644 index 00000000000..3d63d78cabb --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/traits/trait-inheritance-num0.rs b/src/test/ui/traits/trait-inheritance-num0.rs new file mode 100644 index 00000000000..cee52542d38 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num0.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/traits/trait-inheritance-num1.rs b/src/test/ui/traits/trait-inheritance-num1.rs new file mode 100644 index 00000000000..663dd3a5eaf --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num1.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/traits/trait-inheritance-num2.rs b/src/test/ui/traits/trait-inheritance-num2.rs new file mode 100644 index 00000000000..b713c66a37c --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num2.rs @@ -0,0 +1,86 @@ +// 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/src/test/ui/traits/trait-inheritance-num3.rs b/src/test/ui/traits/trait-inheritance-num3.rs new file mode 100644 index 00000000000..c40be6f8354 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num3.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/traits/trait-inheritance-num5.rs b/src/test/ui/traits/trait-inheritance-num5.rs new file mode 100644 index 00000000000..f478618f7b5 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-num5.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/trait-inheritance-overloading-simple.rs b/src/test/ui/traits/trait-inheritance-overloading-simple.rs new file mode 100644 index 00000000000..c306aa2cda0 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-overloading-simple.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs b/src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs new file mode 100644 index 00000000000..2a9acfdd04a --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/trait-inheritance-overloading.rs b/src/test/ui/traits/trait-inheritance-overloading.rs new file mode 100644 index 00000000000..083643e821f --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-overloading.rs @@ -0,0 +1,47 @@ +// 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/src/test/ui/traits/trait-inheritance-self-in-supertype.rs b/src/test/ui/traits/trait-inheritance-self-in-supertype.rs new file mode 100644 index 00000000000..e8a2bd791a5 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-self-in-supertype.rs @@ -0,0 +1,62 @@ +// 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/src/test/ui/traits/trait-inheritance-self.rs b/src/test/ui/traits/trait-inheritance-self.rs new file mode 100644 index 00000000000..5f2559f48eb --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-self.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/traits/trait-inheritance-simple.rs b/src/test/ui/traits/trait-inheritance-simple.rs new file mode 100644 index 00000000000..ca3a284e597 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-simple.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/traits/trait-inheritance-static.rs b/src/test/ui/traits/trait-inheritance-static.rs new file mode 100644 index 00000000000..16218fbd236 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-static.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/trait-inheritance-static2.rs b/src/test/ui/traits/trait-inheritance-static2.rs new file mode 100644 index 00000000000..bc78e1e2328 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-static2.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/traits/trait-inheritance-subst.rs b/src/test/ui/traits/trait-inheritance-subst.rs new file mode 100644 index 00000000000..b2b6503666e --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-subst.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/traits/trait-inheritance-subst2.rs b/src/test/ui/traits/trait-inheritance-subst2.rs new file mode 100644 index 00000000000..ccc9628c777 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-subst2.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/traits/trait-inheritance-visibility.rs b/src/test/ui/traits/trait-inheritance-visibility.rs new file mode 100644 index 00000000000..6ad86492674 --- /dev/null +++ b/src/test/ui/traits/trait-inheritance-visibility.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/trait-inheritance2.rs b/src/test/ui/traits/trait-inheritance2.rs new file mode 100644 index 00000000000..5bfa60b1aec --- /dev/null +++ b/src/test/ui/traits/trait-inheritance2.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/traits/trait-item-inside-macro.rs b/src/test/ui/traits/trait-item-inside-macro.rs new file mode 100644 index 00000000000..54bf872d028 --- /dev/null +++ b/src/test/ui/traits/trait-item-inside-macro.rs @@ -0,0 +1,30 @@ +// 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/src/test/ui/traits/trait-object-auto-dedup.rs b/src/test/ui/traits/trait-object-auto-dedup.rs new file mode 100644 index 00000000000..39d25eb7fe0 --- /dev/null +++ b/src/test/ui/traits/trait-object-auto-dedup.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/traits/trait-object-exclusion.rs b/src/test/ui/traits/trait-object-exclusion.rs new file mode 100644 index 00000000000..0b8b0e2f5ef --- /dev/null +++ b/src/test/ui/traits/trait-object-exclusion.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/traits/trait-object-generics.rs b/src/test/ui/traits/trait-object-generics.rs new file mode 100644 index 00000000000..c18754302b7 --- /dev/null +++ b/src/test/ui/traits/trait-object-generics.rs @@ -0,0 +1,43 @@ +// 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/src/test/ui/traits/trait-object-lifetime-first.rs b/src/test/ui/traits/trait-object-lifetime-first.rs new file mode 100644 index 00000000000..33757cb7c0a --- /dev/null +++ b/src/test/ui/traits/trait-object-lifetime-first.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/traits/trait-object-with-lifetime-bound.rs b/src/test/ui/traits/trait-object-with-lifetime-bound.rs new file mode 100644 index 00000000000..05aab5e3b08 --- /dev/null +++ b/src/test/ui/traits/trait-object-with-lifetime-bound.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/traits/trait-region-pointer-simple.rs b/src/test/ui/traits/trait-region-pointer-simple.rs new file mode 100644 index 00000000000..0456ca93115 --- /dev/null +++ b/src/test/ui/traits/trait-region-pointer-simple.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/traits/trait-safety-ok-cc.rs b/src/test/ui/traits/trait-safety-ok-cc.rs new file mode 100644 index 00000000000..099ba80e5b5 --- /dev/null +++ b/src/test/ui/traits/trait-safety-ok-cc.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/traits/trait-safety-ok.rs b/src/test/ui/traits/trait-safety-ok.rs new file mode 100644 index 00000000000..d456a78b64d --- /dev/null +++ b/src/test/ui/traits/trait-safety-ok.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/traits/trait-static-method-overwriting.rs b/src/test/ui/traits/trait-static-method-overwriting.rs new file mode 100644 index 00000000000..f669ffae6bb --- /dev/null +++ b/src/test/ui/traits/trait-static-method-overwriting.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/traits/trait-to-str.rs b/src/test/ui/traits/trait-to-str.rs new file mode 100644 index 00000000000..9670edbfa2b --- /dev/null +++ b/src/test/ui/traits/trait-to-str.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/traits/trait-where-clause-vs-impl.rs b/src/test/ui/traits/trait-where-clause-vs-impl.rs new file mode 100644 index 00000000000..7cfee27efb3 --- /dev/null +++ b/src/test/ui/traits/trait-where-clause-vs-impl.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/traits/trait-with-bounds-default.rs b/src/test/ui/traits/trait-with-bounds-default.rs new file mode 100644 index 00000000000..31f73d79cc7 --- /dev/null +++ b/src/test/ui/traits/trait-with-bounds-default.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/traits/traits-assoc-type-in-supertrait.rs b/src/test/ui/traits/traits-assoc-type-in-supertrait.rs new file mode 100644 index 00000000000..7d6a754cc5a --- /dev/null +++ b/src/test/ui/traits/traits-assoc-type-in-supertrait.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/traits-conditional-dispatch.rs b/src/test/ui/traits/traits-conditional-dispatch.rs new file mode 100644 index 00000000000..a9c194486fe --- /dev/null +++ b/src/test/ui/traits/traits-conditional-dispatch.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs new file mode 100644 index 00000000000..27ce6d93a81 --- /dev/null +++ b/src/test/ui/traits/traits-conditional-model-fn.rs @@ -0,0 +1,60 @@ +// 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/src/test/ui/traits/traits-default-method-macro.rs b/src/test/ui/traits/traits-default-method-macro.rs new file mode 100644 index 00000000000..2b50ee9b422 --- /dev/null +++ b/src/test/ui/traits/traits-default-method-macro.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/traits/traits-default-method-mut.rs b/src/test/ui/traits/traits-default-method-mut.rs new file mode 100644 index 00000000000..5f8e983b09c --- /dev/null +++ b/src/test/ui/traits/traits-default-method-mut.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/traits/traits-default-method-self.rs b/src/test/ui/traits/traits-default-method-self.rs new file mode 100644 index 00000000000..cdf4d1e148c --- /dev/null +++ b/src/test/ui/traits/traits-default-method-self.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/traits/traits-default-method-trivial.rs b/src/test/ui/traits/traits-default-method-trivial.rs new file mode 100644 index 00000000000..dc41938ec89 --- /dev/null +++ b/src/test/ui/traits/traits-default-method-trivial.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/traits/traits-elaborate-type-region.rs b/src/test/ui/traits/traits-elaborate-type-region.rs new file mode 100644 index 00000000000..03aef0184ba --- /dev/null +++ b/src/test/ui/traits/traits-elaborate-type-region.rs @@ -0,0 +1,49 @@ +// 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/src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs b/src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs new file mode 100644 index 00000000000..e490967b690 --- /dev/null +++ b/src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/traits/traits-issue-22019.rs b/src/test/ui/traits/traits-issue-22019.rs new file mode 100644 index 00000000000..1a887f0f39f --- /dev/null +++ b/src/test/ui/traits/traits-issue-22019.rs @@ -0,0 +1,34 @@ +// 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/src/test/ui/traits/traits-issue-22110.rs b/src/test/ui/traits/traits-issue-22110.rs new file mode 100644 index 00000000000..bdbfee799f1 --- /dev/null +++ b/src/test/ui/traits/traits-issue-22110.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/traits/traits-issue-22655.rs b/src/test/ui/traits/traits-issue-22655.rs new file mode 100644 index 00000000000..bc08ca0a2ba --- /dev/null +++ b/src/test/ui/traits/traits-issue-22655.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/traits/traits-issue-23003.rs b/src/test/ui/traits/traits-issue-23003.rs new file mode 100644 index 00000000000..24c2b2ad660 --- /dev/null +++ b/src/test/ui/traits/traits-issue-23003.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/traits/traits-issue-26339.rs b/src/test/ui/traits/traits-issue-26339.rs new file mode 100644 index 00000000000..bedd87cc4cc --- /dev/null +++ b/src/test/ui/traits/traits-issue-26339.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/traits/traits-multidispatch-infer-convert-target.rs b/src/test/ui/traits/traits-multidispatch-infer-convert-target.rs new file mode 100644 index 00000000000..626e1ae71bc --- /dev/null +++ b/src/test/ui/traits/traits-multidispatch-infer-convert-target.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/traits/traits-repeated-supertrait.rs b/src/test/ui/traits/traits-repeated-supertrait.rs new file mode 100644 index 00000000000..391d19c4385 --- /dev/null +++ b/src/test/ui/traits/traits-repeated-supertrait.rs @@ -0,0 +1,48 @@ +// 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/src/test/ui/traits/ufcs-trait-object.rs b/src/test/ui/traits/ufcs-trait-object.rs new file mode 100644 index 00000000000..700488c22d6 --- /dev/null +++ b/src/test/ui/traits/ufcs-trait-object.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/traits/use-trait-before-def.rs b/src/test/ui/traits/use-trait-before-def.rs new file mode 100644 index 00000000000..1ee2b941909 --- /dev/null +++ b/src/test/ui/traits/use-trait-before-def.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/transmute-non-immediate-to-immediate.rs b/src/test/ui/transmute-non-immediate-to-immediate.rs new file mode 100644 index 00000000000..cf77c113f4c --- /dev/null +++ b/src/test/ui/transmute-non-immediate-to-immediate.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/transmute-specialization.rs b/src/test/ui/transmute-specialization.rs new file mode 100644 index 00000000000..002fba9ce81 --- /dev/null +++ b/src/test/ui/transmute-specialization.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(specialization)] + +trait Specializable { type Output; } + +impl Specializable for T { + default type Output = u16; +} + +fn main() { + unsafe { + std::mem::transmute::::Output>(0); + } +} diff --git a/src/test/ui/trivial-message.rs b/src/test/ui/trivial-message.rs new file mode 100644 index 00000000000..5831e867be5 --- /dev/null +++ b/src/test/ui/trivial-message.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/try-block.rs b/src/test/ui/try-block.rs new file mode 100644 index 00000000000..c29ccc70427 --- /dev/null +++ b/src/test/ui/try-block.rs @@ -0,0 +1,75 @@ +// 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/src/test/ui/try-from-int-error-partial-eq.rs b/src/test/ui/try-from-int-error-partial-eq.rs new file mode 100644 index 00000000000..6ee4a4cf319 --- /dev/null +++ b/src/test/ui/try-from-int-error-partial-eq.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/try-is-identifier-edition2015.rs b/src/test/ui/try-is-identifier-edition2015.rs new file mode 100644 index 00000000000..dfb05599be6 --- /dev/null +++ b/src/test/ui/try-is-identifier-edition2015.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/try-operator-custom.rs b/src/test/ui/try-operator-custom.rs new file mode 100644 index 00000000000..9993061ea61 --- /dev/null +++ b/src/test/ui/try-operator-custom.rs @@ -0,0 +1,63 @@ +// 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/src/test/ui/try-operator-hygiene.rs b/src/test/ui/try-operator-hygiene.rs new file mode 100644 index 00000000000..0b24b4305ac --- /dev/null +++ b/src/test/ui/try-operator-hygiene.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/try-operator.rs b/src/test/ui/try-operator.rs new file mode 100644 index 00000000000..9118e8e7134 --- /dev/null +++ b/src/test/ui/try-operator.rs @@ -0,0 +1,193 @@ +// 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/src/test/ui/try-wait.rs b/src/test/ui/try-wait.rs new file mode 100644 index 00000000000..d8a07c55cf2 --- /dev/null +++ b/src/test/ui/try-wait.rs @@ -0,0 +1,61 @@ +// 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/src/test/ui/try_from.rs b/src/test/ui/try_from.rs new file mode 100644 index 00000000000..50451576f9c --- /dev/null +++ b/src/test/ui/try_from.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/tup.rs b/src/test/ui/tup.rs new file mode 100644 index 00000000000..160477b0b0a --- /dev/null +++ b/src/test/ui/tup.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/tuple-index-fat-types.rs b/src/test/ui/tuple-index-fat-types.rs new file mode 100644 index 00000000000..5dda1ed975c --- /dev/null +++ b/src/test/ui/tuple-index-fat-types.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/tuple-index.rs b/src/test/ui/tuple-index.rs new file mode 100644 index 00000000000..3e1d92b42aa --- /dev/null +++ b/src/test/ui/tuple-index.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/tydesc-name.rs b/src/test/ui/tydesc-name.rs new file mode 100644 index 00000000000..c432e5b5481 --- /dev/null +++ b/src/test/ui/tydesc-name.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/type-ascription.rs b/src/test/ui/type-ascription.rs new file mode 100644 index 00000000000..7adb074428c --- /dev/null +++ b/src/test/ui/type-ascription.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/type-id-higher-rank-2.rs b/src/test/ui/type-id-higher-rank-2.rs new file mode 100644 index 00000000000..5391c849dad --- /dev/null +++ b/src/test/ui/type-id-higher-rank-2.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/type-id-higher-rank.rs b/src/test/ui/type-id-higher-rank.rs new file mode 100644 index 00000000000..355d1109941 --- /dev/null +++ b/src/test/ui/type-id-higher-rank.rs @@ -0,0 +1,72 @@ +// 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/src/test/ui/type-in-nested-module.rs b/src/test/ui/type-in-nested-module.rs new file mode 100644 index 00000000000..8a92f065f1b --- /dev/null +++ b/src/test/ui/type-in-nested-module.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/type-infer-generalize-ty-var.rs b/src/test/ui/type-infer-generalize-ty-var.rs new file mode 100644 index 00000000000..a3d6916cbf7 --- /dev/null +++ b/src/test/ui/type-infer-generalize-ty-var.rs @@ -0,0 +1,56 @@ +// 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/src/test/ui/type-namespace.rs b/src/test/ui/type-namespace.rs new file mode 100644 index 00000000000..3cc0bc447a5 --- /dev/null +++ b/src/test/ui/type-namespace.rs @@ -0,0 +1,7 @@ +// 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/src/test/ui/type-param-constraints.rs b/src/test/ui/type-param-constraints.rs new file mode 100644 index 00000000000..4b42fddaf5c --- /dev/null +++ b/src/test/ui/type-param-constraints.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/type-param.rs b/src/test/ui/type-param.rs new file mode 100644 index 00000000000..f5ac19cf73a --- /dev/null +++ b/src/test/ui/type-param.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/type-params-in-for-each.rs b/src/test/ui/type-params-in-for-each.rs new file mode 100644 index 00000000000..be4a0185eda --- /dev/null +++ b/src/test/ui/type-params-in-for-each.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/type-ptr.rs b/src/test/ui/type-ptr.rs new file mode 100644 index 00000000000..7c2438d38bd --- /dev/null +++ b/src/test/ui/type-ptr.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/type-sizes.rs b/src/test/ui/type-sizes.rs new file mode 100644 index 00000000000..27433fd770b --- /dev/null +++ b/src/test/ui/type-sizes.rs @@ -0,0 +1,116 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![feature(never_type)] + +use std::mem::size_of; + +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 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, +} + +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::(), 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, &())>()); +} diff --git a/src/test/ui/type-use-i1-versus-i8.rs b/src/test/ui/type-use-i1-versus-i8.rs new file mode 100644 index 00000000000..7315cd2feea --- /dev/null +++ b/src/test/ui/type-use-i1-versus-i8.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs b/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs new file mode 100644 index 00000000000..2530a1e966d --- /dev/null +++ b/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs @@ -0,0 +1,9 @@ +// run-pass + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(|| {}); } +} diff --git a/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs new file mode 100644 index 00000000000..1e954f56909 --- /dev/null +++ b/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/typeck_type_placeholder_1.rs b/src/test/ui/typeck_type_placeholder_1.rs new file mode 100644 index 00000000000..ea7aa5285b0 --- /dev/null +++ b/src/test/ui/typeck_type_placeholder_1.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/typeclasses-eq-example-static.rs b/src/test/ui/typeclasses-eq-example-static.rs new file mode 100644 index 00000000000..282d51a93df --- /dev/null +++ b/src/test/ui/typeclasses-eq-example-static.rs @@ -0,0 +1,69 @@ +// 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/src/test/ui/typeclasses-eq-example.rs b/src/test/ui/typeclasses-eq-example.rs new file mode 100644 index 00000000000..8d1d22eb823 --- /dev/null +++ b/src/test/ui/typeclasses-eq-example.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/typeid-intrinsic.rs b/src/test/ui/typeid-intrinsic.rs new file mode 100644 index 00000000000..c2611158e65 --- /dev/null +++ b/src/test/ui/typeid-intrinsic.rs @@ -0,0 +1,87 @@ +// 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!(other1::id_i32_iterator() != other1::id_u32_iterator()); + assert!(TypeId::of::() != TypeId::of::()); + + // Check fn pointer against collisions + assert!(TypeId::of:: A) -> A>() != + TypeId::of:: A, A) -> A>()); +} diff --git a/src/test/ui/typestate-cfg-nesting.rs b/src/test/ui/typestate-cfg-nesting.rs new file mode 100644 index 00000000000..5718e0efd18 --- /dev/null +++ b/src/test/ui/typestate-cfg-nesting.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/typestate-multi-decl.rs b/src/test/ui/typestate-multi-decl.rs new file mode 100644 index 00000000000..9f941620559 --- /dev/null +++ b/src/test/ui/typestate-multi-decl.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let (x, y) = (10, 20); + let z = x + y; + assert_eq!(z, 30); +} diff --git a/src/test/ui/ufcs-polymorphic-paths.rs b/src/test/ui/ufcs-polymorphic-paths.rs new file mode 100644 index 00000000000..a14ebd6a41f --- /dev/null +++ b/src/test/ui/ufcs-polymorphic-paths.rs @@ -0,0 +1,154 @@ +// 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/src/test/ui/ufcs-type-params.rs b/src/test/ui/ufcs-type-params.rs new file mode 100644 index 00000000000..eee2b55b2a0 --- /dev/null +++ b/src/test/ui/ufcs-type-params.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/unary-minus-suffix-inference.rs b/src/test/ui/unary-minus-suffix-inference.rs new file mode 100644 index 00000000000..a4d0a849484 --- /dev/null +++ b/src/test/ui/unary-minus-suffix-inference.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs b/src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs new file mode 100644 index 00000000000..ac0a74eebd5 --- /dev/null +++ b/src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs @@ -0,0 +1,16 @@ +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/src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs b/src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs new file mode 100644 index 00000000000..dfccb02009e --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs new file mode 100644 index 00000000000..a1001673506 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs new file mode 100644 index 00000000000..ca1d31ca544 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-boxed.rs b/src/test/ui/unboxed-closures/unboxed-closures-boxed.rs new file mode 100644 index 00000000000..b2596e49aa7 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-boxed.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs b/src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs new file mode 100644 index 00000000000..cf4d4d3e136 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs new file mode 100644 index 00000000000..e23a75ab334 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs new file mode 100644 index 00000000000..9b8a3f4098c --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs new file mode 100644 index 00000000000..d47ceea0f4f --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs new file mode 100644 index 00000000000..f77733d106d --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs new file mode 100644 index 00000000000..fb24df3c24e --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +// 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 { + let v = counter; + counter += v; + } + }); + assert_eq!(counter, 88); + + call(move || { + // this mutates a moved copy, and hence doesn't affect original + counter += 1; + }); + assert_eq!(counter, 88); +} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs b/src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs new file mode 100644 index 00000000000..39cc260726d --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs new file mode 100644 index 00000000000..1c5e74e593c --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_mut)] +// pretty-expanded FIXME #23616 + +fn main() { + let mut unboxed = || {}; + unboxed(); +} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-drop.rs b/src/test/ui/unboxed-closures/unboxed-closures-drop.rs new file mode 100644 index 00000000000..ba3c61ca22b --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-drop.rs @@ -0,0 +1,117 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs new file mode 100644 index 00000000000..3ee1aeb109b --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs new file mode 100644 index 00000000000..677cd259a4e --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs new file mode 100644 index 00000000000..851f3d2fe9b --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs @@ -0,0 +1,44 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs new file mode 100644 index 00000000000..bd577f7c479 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-generic.rs b/src/test/ui/unboxed-closures/unboxed-closures-generic.rs new file mode 100644 index 00000000000..740b8b2a72f --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-generic.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs new file mode 100644 index 00000000000..e0c9105760d --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs new file mode 100644 index 00000000000..d2eaee30410 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs new file mode 100644 index 00000000000..c3abdd8aab0 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs new file mode 100644 index 00000000000..9135c82b4fd --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(fn_traits)] + +fn main() { + let mut zero = || 0; + let x = zero.call_mut(()); + assert_eq!(x, 0); +} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs new file mode 100644 index 00000000000..73f488a4fbb --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs new file mode 100644 index 00000000000..7ac1ae30f77 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs new file mode 100644 index 00000000000..0fbb504c2ba --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs new file mode 100644 index 00000000000..6381386c4cc --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs new file mode 100644 index 00000000000..3c8ea7d8510 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs new file mode 100644 index 00000000000..fc01bd9b6d9 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs new file mode 100644 index 00000000000..86834f49407 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs @@ -0,0 +1,45 @@ +// 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]: http://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/src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs new file mode 100644 index 00000000000..6a5e5b9c224 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs b/src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs new file mode 100644 index 00000000000..df60b42ab12 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs b/src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs new file mode 100644 index 00000000000..2df360d4a30 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs new file mode 100644 index 00000000000..4388e6bcf77 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs @@ -0,0 +1,26 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs new file mode 100644 index 00000000000..9b519e63a95 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -0,0 +1,30 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![deny(unused_mut)] + +// 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; + } + { + let mut x = 0_usize; + move || x += 1; + } + { + let mut x = 0_usize; + move || set(&mut x); + } + { + let mut x = 0_usize; + move || set(&mut x); + } +} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs new file mode 100644 index 00000000000..2d219643f3e --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-prelude.rs b/src/test/ui/unboxed-closures/unboxed-closures-prelude.rs new file mode 100644 index 00000000000..89a273b7a43 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-prelude.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-simple.rs b/src/test/ui/unboxed-closures/unboxed-closures-simple.rs new file mode 100644 index 00000000000..1449554024c --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-simple.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs b/src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs new file mode 100644 index 00000000000..8ada7494e02 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs new file mode 100644 index 00000000000..054f284ea2a --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let onetime = |x| x; + onetime(0); +} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs b/src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs new file mode 100644 index 00000000000..1ca25517c3c --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs new file mode 100644 index 00000000000..f86499e2e3f --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs @@ -0,0 +1,25 @@ +// run-pass + +// This code used to produce the following ICE: +// +// error: internal compiler error: get_unique_type_id_of_type() - +// unexpected type: closure, +// Closure(syntax::ast::DefId{krate: 0, node: 66}, +// ReScope(63)) +// +// This is a regression test for issue #17021. +// +// compile-flags: -g + +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/src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs b/src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs new file mode 100644 index 00000000000..6f41c35584e --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_mut)] +// pretty-expanded FIXME #23616 + +fn main() { + let mut zero = || {}; + let () = zero(); +} diff --git a/src/test/ui/underscore-lifetimes.rs b/src/test/ui/underscore-lifetimes.rs new file mode 100644 index 00000000000..a1593880d84 --- /dev/null +++ b/src/test/ui/underscore-lifetimes.rs @@ -0,0 +1,38 @@ +// 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/src/test/ui/underscore-method-after-integer.rs b/src/test/ui/underscore-method-after-integer.rs new file mode 100644 index 00000000000..7fb8607f97d --- /dev/null +++ b/src/test/ui/underscore-method-after-integer.rs @@ -0,0 +1,11 @@ +// run-pass + +trait Tr : Sized { + fn _method_on_numbers(self) {} +} + +impl Tr for i32 {} + +fn main() { + 42._method_on_numbers(); +} diff --git a/src/test/ui/uniform-paths/auxiliary/issue-53691.rs b/src/test/ui/uniform-paths/auxiliary/issue-53691.rs new file mode 100644 index 00000000000..a4653317860 --- /dev/null +++ b/src/test/ui/uniform-paths/auxiliary/issue-53691.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod m { pub fn f() {} } +mod n { pub fn g() {} } + +pub use m::f; +pub use n::g; diff --git a/src/test/ui/uniform-paths/basic-nested.rs b/src/test/ui/uniform-paths/basic-nested.rs new file mode 100644 index 00000000000..e4e8b32c70e --- /dev/null +++ b/src/test/ui/uniform-paths/basic-nested.rs @@ -0,0 +1,61 @@ +// 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/src/test/ui/uniform-paths/basic.rs b/src/test/ui/uniform-paths/basic.rs new file mode 100644 index 00000000000..4e2e2dedef6 --- /dev/null +++ b/src/test/ui/uniform-paths/basic.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/uniform-paths/issue-53691.rs b/src/test/ui/uniform-paths/issue-53691.rs new file mode 100644 index 00000000000..5c5ca5b70bb --- /dev/null +++ b/src/test/ui/uniform-paths/issue-53691.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-53691.rs + +extern crate issue_53691; + +fn main() { + issue_53691::f(); + issue_53691::g(); +} diff --git a/src/test/ui/uniform-paths/macros-nested.rs b/src/test/ui/uniform-paths/macros-nested.rs new file mode 100644 index 00000000000..a62a28bb94d --- /dev/null +++ b/src/test/ui/uniform-paths/macros-nested.rs @@ -0,0 +1,53 @@ +// 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/src/test/ui/uniform-paths/macros.rs b/src/test/ui/uniform-paths/macros.rs new file mode 100644 index 00000000000..31b809f0cfd --- /dev/null +++ b/src/test/ui/uniform-paths/macros.rs @@ -0,0 +1,36 @@ +// 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/src/test/ui/uniform-paths/same-crate.rs b/src/test/ui/uniform-paths/same-crate.rs new file mode 100644 index 00000000000..ce4cc13d9ec --- /dev/null +++ b/src/test/ui/uniform-paths/same-crate.rs @@ -0,0 +1,98 @@ +// 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/src/test/ui/unify-return-ty.rs b/src/test/ui/unify-return-ty.rs new file mode 100644 index 00000000000..da1d82e896a --- /dev/null +++ b/src/test/ui/unify-return-ty.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/uninit-empty-types.rs b/src/test/ui/uninit-empty-types.rs new file mode 100644 index 00000000000..0d1235776a6 --- /dev/null +++ b/src/test/ui/uninit-empty-types.rs @@ -0,0 +1,17 @@ +// run-pass +// Test the uninit() construct returning various empty types. + +// pretty-expanded FIXME #23616 + +use std::mem; + +#[derive(Clone)] +struct Foo; + +#[allow(deprecated)] +pub fn main() { + unsafe { + let _x: Foo = mem::uninitialized(); + let _x: [Foo; 2] = mem::uninitialized(); + } +} diff --git a/src/test/ui/union/auxiliary/union.rs b/src/test/ui/union/auxiliary/union.rs new file mode 100644 index 00000000000..e785e35aeb8 --- /dev/null +++ b/src/test/ui/union/auxiliary/union.rs @@ -0,0 +1,4 @@ +pub union U { + pub a: u8, + pub b: u16, +} diff --git a/src/test/ui/union/union-align.rs b/src/test/ui/union/union-align.rs new file mode 100644 index 00000000000..edd83a51169 --- /dev/null +++ b/src/test/ui/union/union-align.rs @@ -0,0 +1,63 @@ +// run-pass +#![allow(dead_code)] + +#![feature(untagged_unions)] + +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))] + 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/src/test/ui/union/union-backcomp.rs b/src/test/ui/union/union-backcomp.rs new file mode 100644 index 00000000000..4efd4c4d3d3 --- /dev/null +++ b/src/test/ui/union/union-backcomp.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/union/union-basic.rs b/src/test/ui/union/union-basic.rs new file mode 100644 index 00000000000..73cc9793f2c --- /dev/null +++ b/src/test/ui/union/union-basic.rs @@ -0,0 +1,59 @@ +// 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/src/test/ui/union/union-c-interop.rs b/src/test/ui/union/union-c-interop.rs new file mode 100644 index 00000000000..00f04d5b7ff --- /dev/null +++ b/src/test/ui/union/union-c-interop.rs @@ -0,0 +1,37 @@ +// 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/src/test/ui/union/union-const-codegen.rs b/src/test/ui/union/union-const-codegen.rs new file mode 100644 index 00000000000..d5b30559595 --- /dev/null +++ b/src/test/ui/union/union-const-codegen.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/union/union-const-eval-field.rs b/src/test/ui/union/union-const-eval-field.rs new file mode 100644 index 00000000000..3b40a21d80d --- /dev/null +++ b/src/test/ui/union/union-const-eval-field.rs @@ -0,0 +1,45 @@ +// 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/src/test/ui/union/union-drop-assign.rs b/src/test/ui/union/union-drop-assign.rs new file mode 100644 index 00000000000..c4349c45464 --- /dev/null +++ b/src/test/ui/union/union-drop-assign.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unions_with_drop_fields)] + +// Drop works for union itself. + +#![feature(untagged_unions)] + +struct S; + +union U { + a: S +} + +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: S }; + assert_eq!(CHECK, 0); + u = U { a: 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/src/test/ui/union/union-drop.rs b/src/test/ui/union/union-drop.rs new file mode 100644 index 00000000000..2060950dda9 --- /dev/null +++ b/src/test/ui/union/union-drop.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unions_with_drop_fields)] + +// Drop works for union itself. + +#![feature(untagged_unions)] + +struct S; + +union U { + a: u8 +} + +union W { + a: S, +} + +union Y { + a: S, +} + +impl Drop for S { + fn drop(&mut self) { + unsafe { CHECK += 10; } + } +} + +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, not 11, dtor of S is not called + { + let y = Y { a: S }; + } + assert_eq!(CHECK, 2); // 2, not 12, dtor of S is not called + } +} diff --git a/src/test/ui/union/union-inherent-method.rs b/src/test/ui/union/union-inherent-method.rs new file mode 100644 index 00000000000..2e75cce7b10 --- /dev/null +++ b/src/test/ui/union/union-inherent-method.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/union/union-macro.rs b/src/test/ui/union/union-macro.rs new file mode 100644 index 00000000000..e938cd5a614 --- /dev/null +++ b/src/test/ui/union/union-macro.rs @@ -0,0 +1,24 @@ +// 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/src/test/ui/union/union-nodrop.rs b/src/test/ui/union/union-nodrop.rs new file mode 100644 index 00000000000..4cd64ddb5d6 --- /dev/null +++ b/src/test/ui/union/union-nodrop.rs @@ -0,0 +1,59 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(untagged_unions)] + +#![allow(unions_with_drop_fields)] +#![allow(dead_code)] + +use std::intrinsics::needs_drop; + +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: NeedDrop }, ()).1; + +// A union that scrubs the drop glue from its inner type +union NoDrop {inner: T} + +// 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: T} + +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/src/test/ui/union/union-nonzero.rs b/src/test/ui/union/union-nonzero.rs new file mode 100644 index 00000000000..bd84b46bf3d --- /dev/null +++ b/src/test/ui/union/union-nonzero.rs @@ -0,0 +1,51 @@ +// 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/src/test/ui/union/union-overwrite.rs b/src/test/ui/union/union-overwrite.rs new file mode 100644 index 00000000000..64c60604ba9 --- /dev/null +++ b/src/test/ui/union/union-overwrite.rs @@ -0,0 +1,73 @@ +// run-pass +#![allow(unions_with_drop_fields)] + +#![feature(untagged_unions)] + +#[repr(C)] +struct Pair(T, U); +#[repr(C)] +struct Triple(T, T, T); + +#[repr(C)] +union U { + a: Pair, + b: B, +} + +#[repr(C)] +union W { + 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/src/test/ui/union/union-packed.rs b/src/test/ui/union/union-packed.rs new file mode 100644 index 00000000000..ceb35d94656 --- /dev/null +++ b/src/test/ui/union/union-packed.rs @@ -0,0 +1,171 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +#![feature(untagged_unions)] + +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)] + 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/src/test/ui/union/union-pat-refutability.rs b/src/test/ui/union/union-pat-refutability.rs new file mode 100644 index 00000000000..ebb06726647 --- /dev/null +++ b/src/test/ui/union/union-pat-refutability.rs @@ -0,0 +1,54 @@ +// 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/src/test/ui/union/union-trait-impl.rs b/src/test/ui/union/union-trait-impl.rs new file mode 100644 index 00000000000..8a7ac817240 --- /dev/null +++ b/src/test/ui/union/union-trait-impl.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/union/union-transmute.rs b/src/test/ui/union/union-transmute.rs new file mode 100644 index 00000000000..ac7dede98a3 --- /dev/null +++ b/src/test/ui/union/union-transmute.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/unique/unique-assign-copy.rs b/src/test/ui/unique/unique-assign-copy.rs new file mode 100644 index 00000000000..19469810237 --- /dev/null +++ b/src/test/ui/unique/unique-assign-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; + j = i.clone(); + *i = 2; + *j = 3; + assert_eq!(*i, 2); + assert_eq!(*j, 3); +} diff --git a/src/test/ui/unique/unique-assign-drop.rs b/src/test/ui/unique/unique-assign-drop.rs new file mode 100644 index 00000000000..32068e79df4 --- /dev/null +++ b/src/test/ui/unique/unique-assign-drop.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-assign-generic.rs b/src/test/ui/unique/unique-assign-generic.rs new file mode 100644 index 00000000000..2d62ce59ad0 --- /dev/null +++ b/src/test/ui/unique/unique-assign-generic.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-assign.rs b/src/test/ui/unique/unique-assign.rs new file mode 100644 index 00000000000..5a88df071a0 --- /dev/null +++ b/src/test/ui/unique/unique-assign.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/unique/unique-autoderef-field.rs b/src/test/ui/unique/unique-autoderef-field.rs new file mode 100644 index 00000000000..0360646f133 --- /dev/null +++ b/src/test/ui/unique/unique-autoderef-field.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/unique/unique-autoderef-index.rs b/src/test/ui/unique/unique-autoderef-index.rs new file mode 100644 index 00000000000..5a3d17a84ef --- /dev/null +++ b/src/test/ui/unique/unique-autoderef-index.rs @@ -0,0 +1,7 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box vec![100]; + assert_eq!((*i)[0], 100); +} diff --git a/src/test/ui/unique/unique-cmp.rs b/src/test/ui/unique/unique-cmp.rs new file mode 100644 index 00000000000..7bbc61d25ac --- /dev/null +++ b/src/test/ui/unique/unique-cmp.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-containing-tag.rs b/src/test/ui/unique/unique-containing-tag.rs new file mode 100644 index 00000000000..f24b3a8645f --- /dev/null +++ b/src/test/ui/unique/unique-containing-tag.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/unique/unique-create.rs b/src/test/ui/unique/unique-create.rs new file mode 100644 index 00000000000..3df0f7d55fd --- /dev/null +++ b/src/test/ui/unique/unique-create.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/unique/unique-decl-init-copy.rs b/src/test/ui/unique/unique-decl-init-copy.rs new file mode 100644 index 00000000000..6ae95949e84 --- /dev/null +++ b/src/test/ui/unique/unique-decl-init-copy.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-decl-init.rs b/src/test/ui/unique/unique-decl-init.rs new file mode 100644 index 00000000000..2c7b9d6054f --- /dev/null +++ b/src/test/ui/unique/unique-decl-init.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 1; + let j = i; + assert_eq!(*j, 1); +} diff --git a/src/test/ui/unique/unique-decl-move.rs b/src/test/ui/unique/unique-decl-move.rs new file mode 100644 index 00000000000..4a5ee56ea92 --- /dev/null +++ b/src/test/ui/unique/unique-decl-move.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + let j = i; + assert_eq!(*j, 100); +} diff --git a/src/test/ui/unique/unique-decl.rs b/src/test/ui/unique/unique-decl.rs new file mode 100644 index 00000000000..84a1b2a5b83 --- /dev/null +++ b/src/test/ui/unique/unique-decl.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] + + +pub fn main() { + let _: Box; +} + +fn f(_i: Box) -> Box { + panic!(); +} diff --git a/src/test/ui/unique/unique-deref.rs b/src/test/ui/unique/unique-deref.rs new file mode 100644 index 00000000000..0c6af0f7f97 --- /dev/null +++ b/src/test/ui/unique/unique-deref.rs @@ -0,0 +1,7 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + assert_eq!(*i, 100); +} diff --git a/src/test/ui/unique/unique-destructure.rs b/src/test/ui/unique/unique-destructure.rs new file mode 100644 index 00000000000..9b9f95dfbca --- /dev/null +++ b/src/test/ui/unique/unique-destructure.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unique/unique-drop-complex.rs b/src/test/ui/unique/unique-drop-complex.rs new file mode 100644 index 00000000000..0b7bda83b3f --- /dev/null +++ b/src/test/ui/unique/unique-drop-complex.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/unique/unique-ffi-symbols.rs b/src/test/ui/unique/unique-ffi-symbols.rs new file mode 100644 index 00000000000..b0fe22bc332 --- /dev/null +++ b/src/test/ui/unique/unique-ffi-symbols.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/unique/unique-fn-arg-move.rs b/src/test/ui/unique/unique-fn-arg-move.rs new file mode 100644 index 00000000000..ff33839e57e --- /dev/null +++ b/src/test/ui/unique/unique-fn-arg-move.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/unique/unique-fn-arg-mut.rs b/src/test/ui/unique/unique-fn-arg-mut.rs new file mode 100644 index 00000000000..e8bb35e4eb0 --- /dev/null +++ b/src/test/ui/unique/unique-fn-arg-mut.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-fn-arg.rs b/src/test/ui/unique/unique-fn-arg.rs new file mode 100644 index 00000000000..75f2a767f59 --- /dev/null +++ b/src/test/ui/unique/unique-fn-arg.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unique/unique-fn-ret.rs b/src/test/ui/unique/unique-fn-ret.rs new file mode 100644 index 00000000000..cd44cfa9836 --- /dev/null +++ b/src/test/ui/unique/unique-fn-ret.rs @@ -0,0 +1,10 @@ +// run-pass +#![feature(box_syntax)] + +fn f() -> Box { + box 100 +} + +pub fn main() { + assert_eq!(f(), box 100); +} diff --git a/src/test/ui/unique/unique-generic-assign.rs b/src/test/ui/unique/unique-generic-assign.rs new file mode 100644 index 00000000000..9c4405aa8ac --- /dev/null +++ b/src/test/ui/unique/unique-generic-assign.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// Issue #976 + + +// pretty-expanded FIXME #23616 + +fn f(x: Box) { + let _x2 = x; +} +pub fn main() { } diff --git a/src/test/ui/unique/unique-in-tag.rs b/src/test/ui/unique/unique-in-tag.rs new file mode 100644 index 00000000000..8d97ebe6590 --- /dev/null +++ b/src/test/ui/unique/unique-in-tag.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/unique/unique-in-vec-copy.rs b/src/test/ui/unique/unique-in-vec-copy.rs new file mode 100644 index 00000000000..8907a8b20a7 --- /dev/null +++ b/src/test/ui/unique/unique-in-vec-copy.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/unique/unique-in-vec.rs b/src/test/ui/unique/unique-in-vec.rs new file mode 100644 index 00000000000..528ea4fb870 --- /dev/null +++ b/src/test/ui/unique/unique-in-vec.rs @@ -0,0 +1,7 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let vect : Vec> = vec![box 100]; + assert_eq!(vect[0], box 100); +} diff --git a/src/test/ui/unique/unique-init.rs b/src/test/ui/unique/unique-init.rs new file mode 100644 index 00000000000..c8a150522fd --- /dev/null +++ b/src/test/ui/unique/unique-init.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let _i: Box<_> = box 100; +} diff --git a/src/test/ui/unique/unique-kinds.rs b/src/test/ui/unique/unique-kinds.rs new file mode 100644 index 00000000000..f369a1e2a19 --- /dev/null +++ b/src/test/ui/unique/unique-kinds.rs @@ -0,0 +1,65 @@ +// 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/src/test/ui/unique/unique-log.rs b/src/test/ui/unique/unique-log.rs new file mode 100644 index 00000000000..27977717706 --- /dev/null +++ b/src/test/ui/unique/unique-log.rs @@ -0,0 +1,7 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + println!("{}", i); +} diff --git a/src/test/ui/unique/unique-match-discrim.rs b/src/test/ui/unique/unique-match-discrim.rs new file mode 100644 index 00000000000..6e6d7432277 --- /dev/null +++ b/src/test/ui/unique/unique-match-discrim.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// Issue #961 + +// pretty-expanded FIXME #23616 + +fn altsimple() { + match Box::new(true) { + _ => { } + } +} +pub fn main() { } diff --git a/src/test/ui/unique/unique-move-drop.rs b/src/test/ui/unique/unique-move-drop.rs new file mode 100644 index 00000000000..e1ea58b39ef --- /dev/null +++ b/src/test/ui/unique/unique-move-drop.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/unique/unique-move-temp.rs b/src/test/ui/unique/unique-move-temp.rs new file mode 100644 index 00000000000..4f5de50b722 --- /dev/null +++ b/src/test/ui/unique/unique-move-temp.rs @@ -0,0 +1,9 @@ +// 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/src/test/ui/unique/unique-move.rs b/src/test/ui/unique/unique-move.rs new file mode 100644 index 00000000000..0f6bff1432b --- /dev/null +++ b/src/test/ui/unique/unique-move.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unique/unique-mutable.rs b/src/test/ui/unique/unique-mutable.rs new file mode 100644 index 00000000000..176cf33d488 --- /dev/null +++ b/src/test/ui/unique/unique-mutable.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_> = box 0; + *i = 1; + assert_eq!(*i, 1); +} diff --git a/src/test/ui/unique/unique-object-move.rs b/src/test/ui/unique/unique-object-move.rs new file mode 100644 index 00000000000..84e8cdb32b8 --- /dev/null +++ b/src/test/ui/unique/unique-object-move.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/unique/unique-pat-2.rs b/src/test/ui/unique/unique-pat-2.rs new file mode 100644 index 00000000000..c18e029b252 --- /dev/null +++ b/src/test/ui/unique/unique-pat-2.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/unique/unique-pat-3.rs b/src/test/ui/unique/unique-pat-3.rs new file mode 100644 index 00000000000..e17b5a3ddb4 --- /dev/null +++ b/src/test/ui/unique/unique-pat-3.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/unique/unique-pat.rs b/src/test/ui/unique/unique-pat.rs new file mode 100644 index 00000000000..b32195ac274 --- /dev/null +++ b/src/test/ui/unique/unique-pat.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn simple() { + match box true { + box true => { } + _ => { panic!(); } + } +} + +pub fn main() { + simple(); +} diff --git a/src/test/ui/unique/unique-rec.rs b/src/test/ui/unique/unique-rec.rs new file mode 100644 index 00000000000..c8bddd246a8 --- /dev/null +++ b/src/test/ui/unique/unique-rec.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unique/unique-send-2.rs b/src/test/ui/unique/unique-send-2.rs new file mode 100644 index 00000000000..22f0e6c3a49 --- /dev/null +++ b/src/test/ui/unique/unique-send-2.rs @@ -0,0 +1,35 @@ +// 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/src/test/ui/unique/unique-send.rs b/src/test/ui/unique/unique-send.rs new file mode 100644 index 00000000000..a5c7561b9ae --- /dev/null +++ b/src/test/ui/unique/unique-send.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/unique/unique-swap.rs b/src/test/ui/unique/unique-swap.rs new file mode 100644 index 00000000000..33a6b3b3ed0 --- /dev/null +++ b/src/test/ui/unique/unique-swap.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/unit.rs b/src/test/ui/unit.rs new file mode 100644 index 00000000000..4f2dd4194a5 --- /dev/null +++ b/src/test/ui/unit.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/unnamed_argument_mode.rs b/src/test/ui/unnamed_argument_mode.rs new file mode 100644 index 00000000000..5b7b4002f47 --- /dev/null +++ b/src/test/ui/unnamed_argument_mode.rs @@ -0,0 +1,14 @@ +// 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/src/test/ui/unreachable-code-1.rs b/src/test/ui/unreachable-code-1.rs new file mode 100644 index 00000000000..ee44f399945 --- /dev/null +++ b/src/test/ui/unreachable-code-1.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/unreachable-code.rs b/src/test/ui/unreachable-code.rs new file mode 100644 index 00000000000..28b938edc63 --- /dev/null +++ b/src/test/ui/unreachable-code.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/unsafe-coercion.rs b/src/test/ui/unsafe-coercion.rs new file mode 100644 index 00000000000..2478deeab0d --- /dev/null +++ b/src/test/ui/unsafe-coercion.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs b/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs new file mode 100644 index 00000000000..38271cc3c78 --- /dev/null +++ b/src/test/ui/unsafe-fn-called-from-unsafe-blk.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; } + +fn g() { + unsafe { + f(); + } +} + +pub fn main() { +} diff --git a/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs new file mode 100644 index 00000000000..26acc913e87 --- /dev/null +++ b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/unsafe-pointer-assignability.rs b/src/test/ui/unsafe-pointer-assignability.rs new file mode 100644 index 00000000000..db822bb6a02 --- /dev/null +++ b/src/test/ui/unsafe-pointer-assignability.rs @@ -0,0 +1,11 @@ +// run-pass + +fn f(x: *const isize) { + unsafe { + assert_eq!(*x, 3); + } +} + +pub fn main() { + f(&3); +} diff --git a/src/test/ui/unsized-locals/autoderef.rs b/src/test/ui/unsized-locals/autoderef.rs new file mode 100644 index 00000000000..7f2d2f9c7ef --- /dev/null +++ b/src/test/ui/unsized-locals/autoderef.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(unsized_locals)] + +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/src/test/ui/unsized-locals/box-fnonce.rs b/src/test/ui/unsized-locals/box-fnonce.rs new file mode 100644 index 00000000000..8b2f9b4c9fc --- /dev/null +++ b/src/test/ui/unsized-locals/box-fnonce.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs new file mode 100644 index 00000000000..8b39a99da58 --- /dev/null +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs @@ -0,0 +1,23 @@ +// run-pass + +#![feature(unsized_locals)] + +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/src/test/ui/unsized-locals/reference-unsized-locals.rs b/src/test/ui/unsized-locals/reference-unsized-locals.rs new file mode 100644 index 00000000000..1560d25d4b0 --- /dev/null +++ b/src/test/ui/unsized-locals/reference-unsized-locals.rs @@ -0,0 +1,9 @@ +// run-pass + +#![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/src/test/ui/unsized-locals/simple-unsized-locals.rs b/src/test/ui/unsized-locals/simple-unsized-locals.rs new file mode 100644 index 00000000000..05955919245 --- /dev/null +++ b/src/test/ui/unsized-locals/simple-unsized-locals.rs @@ -0,0 +1,8 @@ +// run-pass + +#![feature(unsized_locals)] + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let _foo: [u8] = *foo; +} diff --git a/src/test/ui/unsized-locals/unsized-parameters.rs b/src/test/ui/unsized-locals/unsized-parameters.rs new file mode 100644 index 00000000000..3624154d5c4 --- /dev/null +++ b/src/test/ui/unsized-locals/unsized-parameters.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(unsized_locals)] + +pub fn f0(_f: dyn FnOnce()) {} +pub fn f1(_s: str) {} +pub fn f2((_x, _y): (i32, [i32])) {} + +fn main() { + let foo = "foo".to_string().into_boxed_str(); + f1(*foo); +} diff --git a/src/test/ui/unsized-tuple-impls.rs b/src/test/ui/unsized-tuple-impls.rs new file mode 100644 index 00000000000..5e385f33bee --- /dev/null +++ b/src/test/ui/unsized-tuple-impls.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/unsized.rs b/src/test/ui/unsized.rs new file mode 100644 index 00000000000..54304834d4b --- /dev/null +++ b/src/test/ui/unsized.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/unsized2.rs b/src/test/ui/unsized2.rs new file mode 100644 index 00000000000..be4406399fd --- /dev/null +++ b/src/test/ui/unsized2.rs @@ -0,0 +1,97 @@ +// 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/src/test/ui/unused-move-capture.rs b/src/test/ui/unused-move-capture.rs new file mode 100644 index 00000000000..e9d4684736e --- /dev/null +++ b/src/test/ui/unused-move-capture.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/unused-move.rs b/src/test/ui/unused-move.rs new file mode 100644 index 00000000000..37aee22f85d --- /dev/null +++ b/src/test/ui/unused-move.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/unwind-resource.rs b/src/test/ui/unwind-resource.rs new file mode 100644 index 00000000000..a063bef0822 --- /dev/null +++ b/src/test/ui/unwind-resource.rs @@ -0,0 +1,39 @@ +// 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/src/test/ui/unwind-unique.rs b/src/test/ui/unwind-unique.rs new file mode 100644 index 00000000000..ea3089e747f --- /dev/null +++ b/src/test/ui/unwind-unique.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/use-crate-name-alias.rs b/src/test/ui/use-crate-name-alias.rs new file mode 100644 index 00000000000..0920d968585 --- /dev/null +++ b/src/test/ui/use-crate-name-alias.rs @@ -0,0 +1,7 @@ +// run-pass +// Issue #1706 +// pretty-expanded FIXME #23616 + +extern crate std as stdlib; + +pub fn main() {} diff --git a/src/test/ui/use-import-export.rs b/src/test/ui/use-import-export.rs new file mode 100644 index 00000000000..07a6866ba66 --- /dev/null +++ b/src/test/ui/use-import-export.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/use-keyword-2.rs b/src/test/ui/use-keyword-2.rs new file mode 100644 index 00000000000..ebddb5d1a48 --- /dev/null +++ b/src/test/ui/use-keyword-2.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/use-mod.rs b/src/test/ui/use-mod.rs new file mode 100644 index 00000000000..84da2e70878 --- /dev/null +++ b/src/test/ui/use-mod.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/use-nested-groups.rs b/src/test/ui/use-nested-groups.rs new file mode 100644 index 00000000000..5c739709e9e --- /dev/null +++ b/src/test/ui/use-nested-groups.rs @@ -0,0 +1,32 @@ +// 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/src/test/ui/use.rs b/src/test/ui/use.rs new file mode 100644 index 00000000000..1beee4a5143 --- /dev/null +++ b/src/test/ui/use.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/use_inline_dtor.rs b/src/test/ui/use_inline_dtor.rs new file mode 100644 index 00000000000..ac916de4646 --- /dev/null +++ b/src/test/ui/use_inline_dtor.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/using-target-feature-unstable.rs b/src/test/ui/using-target-feature-unstable.rs new file mode 100644 index 00000000000..c5da45c0854 --- /dev/null +++ b/src/test/ui/using-target-feature-unstable.rs @@ -0,0 +1,11 @@ +// 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/src/test/ui/utf8-bom.rs b/src/test/ui/utf8-bom.rs new file mode 100644 index 00000000000..a3cb0e9a52a --- /dev/null +++ b/src/test/ui/utf8-bom.rs @@ -0,0 +1,6 @@ +// run-pass +// + +// This file has utf-8 BOM, it should be compiled normally without error. + +pub fn main() {} diff --git a/src/test/ui/utf8.rs b/src/test/ui/utf8.rs new file mode 100644 index 00000000000..75b6ddf7895 --- /dev/null +++ b/src/test/ui/utf8.rs @@ -0,0 +1,50 @@ +// 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/src/test/ui/utf8_chars.rs b/src/test/ui/utf8_chars.rs new file mode 100644 index 00000000000..d764509813d --- /dev/null +++ b/src/test/ui/utf8_chars.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/variadic-ffi.rs b/src/test/ui/variadic-ffi.rs new file mode 100644 index 00000000000..3232a11d726 --- /dev/null +++ b/src/test/ui/variadic-ffi.rs @@ -0,0 +1,84 @@ +// 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/src/test/ui/variance-intersection-of-ref-and-opt-ref.rs b/src/test/ui/variance-intersection-of-ref-and-opt-ref.rs new file mode 100644 index 00000000000..74707a98d32 --- /dev/null +++ b/src/test/ui/variance-intersection-of-ref-and-opt-ref.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/variance-iterators-in-libcore.rs b/src/test/ui/variance-iterators-in-libcore.rs new file mode 100644 index 00000000000..2ab3a8ab5c1 --- /dev/null +++ b/src/test/ui/variance-iterators-in-libcore.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(warnings)] + +use std::iter::Zip; + +fn zip_covariant<'a, A, B>(iter: Zip<&'static A, &'static B>) -> Zip<&'a A, &'a B> { iter } + +fn main() { } diff --git a/src/test/ui/volatile-fat-ptr.rs b/src/test/ui/volatile-fat-ptr.rs new file mode 100644 index 00000000000..f73e7e1c391 --- /dev/null +++ b/src/test/ui/volatile-fat-ptr.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/wait-forked-but-failed-child.rs b/src/test/ui/wait-forked-but-failed-child.rs new file mode 100644 index 00000000000..434361b40de --- /dev/null +++ b/src/test/ui/wait-forked-but-failed-child.rs @@ -0,0 +1,62 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![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/src/test/ui/warn-ctypes-inhibit.rs b/src/test/ui/warn-ctypes-inhibit.rs new file mode 100644 index 00000000000..ab9634df65c --- /dev/null +++ b/src/test/ui/warn-ctypes-inhibit.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/weak-lang-item.rs b/src/test/ui/weak-lang-item.rs new file mode 100644 index 00000000000..a429d8fabc7 --- /dev/null +++ b/src/test/ui/weak-lang-item.rs @@ -0,0 +1,15 @@ +// 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/src/test/ui/weak-new-uninhabited-issue-48493.rs b/src/test/ui/weak-new-uninhabited-issue-48493.rs new file mode 100644 index 00000000000..644fc8c2483 --- /dev/null +++ b/src/test/ui/weak-new-uninhabited-issue-48493.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + enum Void {} + std::rc::Weak::::new(); + std::sync::Weak::::new(); +} diff --git a/src/test/ui/weird-exit-code.rs b/src/test/ui/weird-exit-code.rs new file mode 100644 index 00000000000..a067b7b5b1f --- /dev/null +++ b/src/test/ui/weird-exit-code.rs @@ -0,0 +1,28 @@ +// 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/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs new file mode 100644 index 00000000000..ca68a5af0dd --- /dev/null +++ b/src/test/ui/weird-exprs.rs @@ -0,0 +1,180 @@ +// run-pass + +#![feature(generators)] + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![allow(unreachable_code)] +#![allow(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/src/test/ui/wf-bound-region-in-object-type.rs b/src/test/ui/wf-bound-region-in-object-type.rs new file mode 100644 index 00000000000..7c4dd3ec84f --- /dev/null +++ b/src/test/ui/wf-bound-region-in-object-type.rs @@ -0,0 +1,22 @@ +// 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/src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs b/src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs new file mode 100644 index 00000000000..7c8043b2002 --- /dev/null +++ b/src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs @@ -0,0 +1,19 @@ +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/src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs b/src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs new file mode 100644 index 00000000000..cf7d06b6179 --- /dev/null +++ b/src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs @@ -0,0 +1,23 @@ +// 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/src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs b/src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs new file mode 100644 index 00000000000..6fc570b9b5b --- /dev/null +++ b/src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs @@ -0,0 +1,18 @@ +// 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/src/test/ui/where-clauses/where-clause-region-outlives.rs b/src/test/ui/where-clauses/where-clause-region-outlives.rs new file mode 100644 index 00000000000..84925345de1 --- /dev/null +++ b/src/test/ui/where-clauses/where-clause-region-outlives.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/where-clauses/where-clauses-cross-crate.rs b/src/test/ui/where-clauses/where-clauses-cross-crate.rs new file mode 100644 index 00000000000..9edf0bd5b1d --- /dev/null +++ b/src/test/ui/where-clauses/where-clauses-cross-crate.rs @@ -0,0 +1,13 @@ +// 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/src/test/ui/where-clauses/where-clauses-lifetimes.rs b/src/test/ui/where-clauses/where-clauses-lifetimes.rs new file mode 100644 index 00000000000..4bfd9e6590f --- /dev/null +++ b/src/test/ui/where-clauses/where-clauses-lifetimes.rs @@ -0,0 +1,10 @@ +// 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/src/test/ui/where-clauses/where-clauses-method.rs b/src/test/ui/where-clauses/where-clauses-method.rs new file mode 100644 index 00000000000..feecff43565 --- /dev/null +++ b/src/test/ui/where-clauses/where-clauses-method.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/where-clauses/where-clauses-unboxed-closures.rs b/src/test/ui/where-clauses/where-clauses-unboxed-closures.rs new file mode 100644 index 00000000000..6964cfa2eb0 --- /dev/null +++ b/src/test/ui/where-clauses/where-clauses-unboxed-closures.rs @@ -0,0 +1,17 @@ +// 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/src/test/ui/where-clauses/where-clauses.rs b/src/test/ui/where-clauses/where-clauses.rs new file mode 100644 index 00000000000..905ef7c5e8c --- /dev/null +++ b/src/test/ui/where-clauses/where-clauses.rs @@ -0,0 +1,27 @@ +// 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/src/test/ui/wrapping-int-api.rs b/src/test/ui/wrapping-int-api.rs new file mode 100644 index 00000000000..2a5baad8b78 --- /dev/null +++ b/src/test/ui/wrapping-int-api.rs @@ -0,0 +1,225 @@ +// run-pass +// Test inherent wrapping_* methods for {i,u}{size,8,16,32,64}. + +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/src/test/ui/write-fmt-errors.rs b/src/test/ui/write-fmt-errors.rs new file mode 100644 index 00000000000..7dd98564425 --- /dev/null +++ b/src/test/ui/write-fmt-errors.rs @@ -0,0 +1,46 @@ +// 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/src/test/ui/writealias.rs b/src/test/ui/writealias.rs new file mode 100644 index 00000000000..8ba4b09ae29 --- /dev/null +++ b/src/test/ui/writealias.rs @@ -0,0 +1,19 @@ +// 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/src/test/ui/wrong-hashset-issue-42918.rs b/src/test/ui/wrong-hashset-issue-42918.rs new file mode 100644 index 00000000000..ef834d915c9 --- /dev/null +++ b/src/test/ui/wrong-hashset-issue-42918.rs @@ -0,0 +1,31 @@ +// 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/src/test/ui/x86stdcall.rs b/src/test/ui/x86stdcall.rs new file mode 100644 index 00000000000..fc67ccdc8c4 --- /dev/null +++ b/src/test/ui/x86stdcall.rs @@ -0,0 +1,36 @@ +// 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 = "solaris"))] +pub fn main() { } diff --git a/src/test/ui/x86stdcall2.rs b/src/test/ui/x86stdcall2.rs new file mode 100644 index 00000000000..563e3aba632 --- /dev/null +++ b/src/test/ui/x86stdcall2.rs @@ -0,0 +1,33 @@ +// 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/src/test/ui/yield.rs b/src/test/ui/yield.rs new file mode 100644 index 00000000000..e83ba556078 --- /dev/null +++ b/src/test/ui/yield.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/yield1.rs b/src/test/ui/yield1.rs new file mode 100644 index 00000000000..002e590550c --- /dev/null +++ b/src/test/ui/yield1.rs @@ -0,0 +1,16 @@ +// 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/src/test/ui/yield2.rs b/src/test/ui/yield2.rs new file mode 100644 index 00000000000..376faab0c48 --- /dev/null +++ b/src/test/ui/yield2.rs @@ -0,0 +1,8 @@ +// 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/src/test/ui/z-crate-attr.rs b/src/test/ui/z-crate-attr.rs new file mode 100644 index 00000000000..1021774fc5f --- /dev/null +++ b/src/test/ui/z-crate-attr.rs @@ -0,0 +1,12 @@ +// 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/src/test/ui/zero-sized/zero-size-type-destructors.rs b/src/test/ui/zero-sized/zero-size-type-destructors.rs new file mode 100644 index 00000000000..98b5a439c82 --- /dev/null +++ b/src/test/ui/zero-sized/zero-size-type-destructors.rs @@ -0,0 +1,21 @@ +// 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/src/test/ui/zero-sized/zero-sized-binary-heap-push.rs b/src/test/ui/zero-sized/zero-sized-binary-heap-push.rs new file mode 100644 index 00000000000..6553c5adbe7 --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-binary-heap-push.rs @@ -0,0 +1,20 @@ +// 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/src/test/ui/zero-sized/zero-sized-btreemap-insert.rs b/src/test/ui/zero-sized/zero-sized-btreemap-insert.rs new file mode 100644 index 00000000000..52edb33d6ad --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-btreemap-insert.rs @@ -0,0 +1,25 @@ +// 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/src/test/ui/zero-sized/zero-sized-linkedlist-push.rs b/src/test/ui/zero-sized/zero-sized-linkedlist-push.rs new file mode 100644 index 00000000000..03724085f5f --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-linkedlist-push.rs @@ -0,0 +1,29 @@ +// 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/src/test/ui/zero-sized/zero-sized-tuple-struct.rs b/src/test/ui/zero-sized/zero-sized-tuple-struct.rs new file mode 100644 index 00000000000..6c438720e5d --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-tuple-struct.rs @@ -0,0 +1,12 @@ +// run-pass +#![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); +} diff --git a/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs b/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs new file mode 100644 index 00000000000..c541208703b --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs @@ -0,0 +1,32 @@ +// run-pass +use std::collections::VecDeque; +use std::iter::Iterator; + +fn main() { + const N: usize = 8; + + // Zero sized type + struct Zst; + + // Test that for all possible sequences of push_front / push_back, + // we end up with a deque of the correct size + + for len in 0..N { + let mut tester = VecDeque::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for case in 0..(1 << len) { + assert_eq!(tester.len(), 0); + for bit in 0..len { + if case & (1 << bit) != 0 { + tester.push_front(Zst); + } else { + tester.push_back(Zst); + } + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } + } +} diff --git a/src/test/ui/zero-sized/zero-sized-vec-push.rs b/src/test/ui/zero-sized/zero-sized-vec-push.rs new file mode 100644 index 00000000000..9e9fbc972d5 --- /dev/null +++ b/src/test/ui/zero-sized/zero-sized-vec-push.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_variables)] +use std::iter::Iterator; +use std::vec::Vec; + +fn main() { + const N: usize = 8; + + for len in 0..N { + let mut tester = Vec::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(); + } +} -- cgit 1.4.1-3-g733a5

Parser for P { - type Input = (); -} - -fn main() { -} diff --git a/src/test/run-pass/associated-types/associated-types-iterator-binding.rs b/src/test/run-pass/associated-types/associated-types-iterator-binding.rs deleted file mode 100644 index 7c5528c986e..00000000000 --- a/src/test/run-pass/associated-types/associated-types-iterator-binding.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -fn pairwise_sub>(mut t: T) -> isize { - let mut result = 0; - loop { - let front = t.next(); - let back = t.next_back(); - match (front, back) { - (Some(f), Some(b)) => { result += b - f; } - _ => { return result; } - } - } -} - -fn main() { - let v = vec![1, 2, 3, 4, 5, 6]; - let r = pairwise_sub(v.into_iter()); - assert_eq!(r, 9); -} diff --git a/src/test/run-pass/associated-types/associated-types-method.rs b/src/test/run-pass/associated-types/associated-types-method.rs deleted file mode 100644 index 64132cfeed7..00000000000 --- a/src/test/run-pass/associated-types/associated-types-method.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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/src/test/run-pass/associated-types/associated-types-nested-projections.rs b/src/test/run-pass/associated-types/associated-types-nested-projections.rs deleted file mode 100644 index 76ba7496250..00000000000 --- a/src/test/run-pass/associated-types/associated-types-nested-projections.rs +++ /dev/null @@ -1,44 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// Test that we can resolve nested projection types. Issue #20666. - -// pretty-expanded FIXME #23616 - -use std::slice; - -trait Bound {} - -impl<'a> Bound for &'a i32 {} - -trait IntoIterator { - type Iter: Iterator; - - fn into_iter(self) -> Self::Iter; -} - -impl<'a, T> IntoIterator for &'a [T; 3] { - type Iter = slice::Iter<'a, T>; - - fn into_iter(self) -> slice::Iter<'a, T> { - self.iter() - } -} - -fn foo(x: X) where - X: IntoIterator, - <::Iter as Iterator>::Item: Bound, -{ -} - -fn bar(x: X) where - T: Bound, - I: Iterator, - X: IntoIterator, -{ - -} - -fn main() { - foo(&[0, 1, 2]); - bar(&[0, 1, 2]); -} diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs deleted file mode 100644 index 7c54efb83c2..00000000000 --- a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -#![allow(unused_variables)] -// Test that we normalize associated types that appear in a bound that -// contains a binding. Issue #21664. - -// pretty-expanded FIXME #23616 - -#![allow(dead_code)] - -pub trait Integral { - type Opposite; -} - -impl Integral for i32 { - type Opposite = u32; -} - -impl Integral for u32 { - type Opposite = i32; -} - -pub trait FnLike { - type R; - - fn dummy(&self, a: A) -> Self::R { loop { } } -} - -fn foo() - where T : FnLike<::Opposite, R=bool> -{ - bar::(); -} - -fn bar() - where T : FnLike -{} - -fn main() { } diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs deleted file mode 100644 index e09aa3663c6..00000000000 --- a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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