]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #89144 - sexxi-goose:insig_stdlib, r=nikomatsakis
authorbors <bors@rust-lang.org>
Sun, 26 Sep 2021 19:36:00 +0000 (19:36 +0000)
committerbors <bors@rust-lang.org>
Sun, 26 Sep 2021 19:36:00 +0000 (19:36 +0000)
2229: Mark insignificant dtor in stdlib

I looked at all public [stdlib Drop implementations](https://doc.rust-lang.org/stable/std/ops/trait.Drop.html#implementors) and categorized them into Insigificant/Maybe/Significant Drop.

Reasons are noted here: https://docs.google.com/spreadsheets/d/19edb9r5lo2UqMrCOVjV0fwcSdS-R7qvKNL76q7tO8VA/edit#gid=1838773501

One thing missing from this PR is tagging HashMap as insigificant destructor as that needs some discussion.

r? `@Mark-Simulacrum`

cc `@nikomatsakis`

943 files changed:
Cargo.lock
RELEASES.md
compiler/rustc/Cargo.toml
compiler/rustc_apfloat/Cargo.toml
compiler/rustc_arena/Cargo.toml
compiler/rustc_ast/Cargo.toml
compiler/rustc_ast_lowering/Cargo.toml
compiler/rustc_ast_lowering/src/expr.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/path.rs
compiler/rustc_ast_passes/Cargo.toml
compiler/rustc_ast_pretty/Cargo.toml
compiler/rustc_attr/Cargo.toml
compiler/rustc_borrowck/Cargo.toml
compiler/rustc_borrowck/src/invalidation.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/region_infer/opaque_types.rs
compiler/rustc_borrowck/src/type_check/canonical.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_builtin_macros/Cargo.toml
compiler/rustc_builtin_macros/src/cfg_eval.rs
compiler/rustc_builtin_macros/src/derive.rs
compiler/rustc_builtin_macros/src/format.rs
compiler/rustc_codegen_cranelift/Cargo.toml
compiler/rustc_codegen_cranelift/src/base.rs
compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs
compiler/rustc_codegen_llvm/Cargo.toml
compiler/rustc_codegen_llvm/src/attributes.rs
compiler/rustc_codegen_llvm/src/back/lto.rs
compiler/rustc_codegen_llvm/src/back/write.rs
compiler/rustc_codegen_llvm/src/intrinsic.rs
compiler/rustc_codegen_llvm/src/llvm/ffi.rs
compiler/rustc_codegen_llvm/src/llvm_util.rs
compiler/rustc_codegen_llvm/src/type_of.rs
compiler/rustc_codegen_ssa/Cargo.toml
compiler/rustc_codegen_ssa/src/mir/block.rs
compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
compiler/rustc_codegen_ssa/src/mir/mod.rs
compiler/rustc_codegen_ssa/src/mir/rvalue.rs
compiler/rustc_const_eval/Cargo.toml
compiler/rustc_const_eval/src/interpret/step.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
compiler/rustc_const_eval/src/transform/promote_consts.rs
compiler/rustc_data_structures/Cargo.toml
compiler/rustc_data_structures/src/graph/scc/mod.rs
compiler/rustc_data_structures/src/lib.rs
compiler/rustc_data_structures/src/sorted_map.rs
compiler/rustc_data_structures/src/steal.rs
compiler/rustc_driver/Cargo.toml
compiler/rustc_error_codes/Cargo.toml
compiler/rustc_errors/Cargo.toml
compiler/rustc_errors/src/lib.rs
compiler/rustc_expand/Cargo.toml
compiler/rustc_expand/src/module.rs
compiler/rustc_expand/src/proc_macro_server.rs
compiler/rustc_feature/Cargo.toml
compiler/rustc_feature/src/accepted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_fs_util/Cargo.toml
compiler/rustc_graphviz/Cargo.toml
compiler/rustc_hir/Cargo.toml
compiler/rustc_hir/src/arena.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_hir/src/intravisit.rs
compiler/rustc_hir_pretty/Cargo.toml
compiler/rustc_incremental/Cargo.toml
compiler/rustc_index/Cargo.toml
compiler/rustc_index/src/bit_set.rs
compiler/rustc_index/src/vec.rs
compiler/rustc_infer/Cargo.toml
compiler/rustc_infer/src/infer/canonical/query_response.rs
compiler/rustc_infer/src/infer/combine.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/infer/nll_relate/mod.rs
compiler/rustc_infer/src/infer/projection.rs [new file with mode: 0644]
compiler/rustc_infer/src/infer/sub.rs
compiler/rustc_infer/src/infer/type_variable.rs
compiler/rustc_infer/src/traits/engine.rs
compiler/rustc_infer/src/traits/util.rs
compiler/rustc_interface/Cargo.toml
compiler/rustc_interface/src/lib.rs
compiler/rustc_interface/src/passes.rs
compiler/rustc_interface/src/util.rs
compiler/rustc_lexer/Cargo.toml
compiler/rustc_lint/Cargo.toml
compiler/rustc_lint/src/array_into_iter.rs
compiler/rustc_lint/src/builtin.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint/src/non_fmt_panic.rs
compiler/rustc_lint_defs/Cargo.toml
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_llvm/Cargo.toml
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
compiler/rustc_macros/Cargo.toml
compiler/rustc_metadata/Cargo.toml
compiler/rustc_metadata/src/dependency_format.rs
compiler/rustc_metadata/src/native_libs.rs
compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_middle/Cargo.toml
compiler/rustc_middle/src/hir/map/collector.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_middle/src/ich/hcx.rs
compiler/rustc_middle/src/ich/impls_ty.rs
compiler/rustc_middle/src/ich/mod.rs
compiler/rustc_middle/src/middle/region.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/tcx.rs
compiler/rustc_middle/src/mir/type_foldable.rs
compiler/rustc_middle/src/mir/visit.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/traits/specialization_graph.rs
compiler/rustc_middle/src/ty/instance.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_middle/src/ty/structural_impls.rs
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_middle/src/ty/trait_def.rs
compiler/rustc_mir_build/Cargo.toml
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_mir_dataflow/Cargo.toml
compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
compiler/rustc_mir_dataflow/src/move_paths/builder.rs
compiler/rustc_mir_transform/Cargo.toml
compiler/rustc_mir_transform/src/const_prop.rs
compiler/rustc_mir_transform/src/coverage/test_macros/Cargo.toml
compiler/rustc_mir_transform/src/dest_prop.rs
compiler/rustc_mir_transform/src/separate_const_switch.rs
compiler/rustc_mir_transform/src/shim.rs
compiler/rustc_monomorphize/Cargo.toml
compiler/rustc_parse/Cargo.toml
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
compiler/rustc_parse/src/lib.rs
compiler/rustc_parse/src/parser/diagnostics.rs
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/item.rs
compiler/rustc_parse/src/validate_attr.rs
compiler/rustc_parse_format/Cargo.toml
compiler/rustc_passes/Cargo.toml
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/hir_id_validator.rs
compiler/rustc_plugin_impl/Cargo.toml
compiler/rustc_privacy/Cargo.toml
compiler/rustc_privacy/src/lib.rs
compiler/rustc_query_impl/Cargo.toml
compiler/rustc_query_impl/src/plumbing.rs
compiler/rustc_query_system/Cargo.toml
compiler/rustc_resolve/Cargo.toml
compiler/rustc_resolve/src/build_reduced_graph.rs
compiler/rustc_resolve/src/diagnostics.rs
compiler/rustc_resolve/src/imports.rs
compiler/rustc_resolve/src/late.rs
compiler/rustc_resolve/src/late/lifetimes.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_resolve/src/macros.rs
compiler/rustc_save_analysis/Cargo.toml
compiler/rustc_serialize/Cargo.toml
compiler/rustc_session/Cargo.toml
compiler/rustc_session/src/session.rs
compiler/rustc_span/Cargo.toml
compiler/rustc_span/src/lib.rs
compiler/rustc_span/src/source_map.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_symbol_mangling/Cargo.toml
compiler/rustc_target/Cargo.toml
compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
compiler/rustc_trait_selection/Cargo.toml
compiler/rustc_trait_selection/src/autoderef.rs
compiler/rustc_trait_selection/src/infer.rs
compiler/rustc_trait_selection/src/opaque_types.rs
compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/fulfill.rs
compiler/rustc_trait_selection/src/traits/mod.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/relationships.rs [new file with mode: 0644]
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
compiler/rustc_trait_selection/src/traits/util.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_traits/Cargo.toml
compiler/rustc_traits/src/type_op.rs
compiler/rustc_ty_utils/Cargo.toml
compiler/rustc_ty_utils/src/ty.rs
compiler/rustc_type_ir/Cargo.toml
compiler/rustc_typeck/Cargo.toml
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/check/_match.rs
compiler/rustc_typeck/src/check/callee.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/coercion.rs
compiler/rustc_typeck/src/check/expr.rs
compiler/rustc_typeck/src/check/fallback.rs
compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
compiler/rustc_typeck/src/check/generator_interior.rs
compiler/rustc_typeck/src/check/inherited.rs
compiler/rustc_typeck/src/check/method/mod.rs
compiler/rustc_typeck/src/check/method/probe.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/upvar.rs
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/coherence/inherent_impls.rs
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect/type_of.rs
compiler/rustc_typeck/src/hir_wf_check.rs
compiler/rustc_typeck/src/impl_wf_check.rs
compiler/rustc_typeck/src/outlives/mod.rs
compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
library/alloc/src/alloc.rs
library/alloc/src/boxed.rs
library/alloc/src/collections/binary_heap.rs
library/alloc/src/collections/btree/map.rs
library/alloc/src/collections/btree/set.rs
library/alloc/src/collections/linked_list.rs
library/alloc/src/collections/vec_deque/into_iter.rs
library/alloc/src/fmt.rs
library/alloc/src/rc.rs
library/alloc/src/string.rs
library/alloc/src/sync.rs
library/alloc/src/vec/mod.rs
library/alloc/tests/lib.rs
library/core/src/ascii.rs
library/core/src/fmt/mod.rs
library/core/src/iter/adapters/map_while.rs
library/core/src/iter/adapters/mod.rs
library/core/src/iter/mod.rs
library/core/src/iter/traits/iterator.rs
library/core/src/num/int_macros.rs
library/core/src/num/uint_macros.rs
library/core/src/option.rs
library/core/src/panicking.rs
library/core/src/pin.rs
library/core/src/result.rs
library/core/src/stream/stream/mod.rs
library/core/src/task/poll.rs
library/core/src/time.rs
library/core/tests/lib.rs
library/core/tests/num/int_macros.rs
library/core/tests/num/uint_macros.rs
library/core/tests/time.rs
library/std/Cargo.toml
library/std/src/collections/hash/map.rs
library/std/src/collections/hash/set.rs
library/std/src/collections/mod.rs
library/std/src/error.rs
library/std/src/ffi/c_str.rs
library/std/src/ffi/mod.rs
library/std/src/ffi/os_str.rs
library/std/src/fs.rs
library/std/src/io/buffered/bufreader.rs
library/std/src/io/buffered/bufwriter.rs
library/std/src/io/cursor.rs
library/std/src/io/mod.rs
library/std/src/io/util.rs
library/std/src/net/addr.rs
library/std/src/net/mod.rs
library/std/src/os/raw/char.md
library/std/src/path.rs
library/std/src/sync/mpsc/shared.rs
library/std/src/sys/windows/fs.rs
library/std/src/sys/windows/stdio_uwp.rs
library/std/src/time.rs
library/test/Cargo.toml
src/bootstrap/Cargo.toml
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/doc.rs
src/bootstrap/lib.rs
src/bootstrap/test.rs
src/build_helper/Cargo.toml
src/doc/rustdoc/src/unstable-features.md
src/doc/unstable-book/src/language-features/closure-track-caller.md [new file with mode: 0644]
src/etc/test-float-parse/Cargo.toml
src/librustdoc/Cargo.toml
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/blanket_impl.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/clean/utils.rs
src/librustdoc/core.rs
src/librustdoc/doctest.rs
src/librustdoc/fold.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/json/conversions.rs
src/librustdoc/lib.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/librustdoc/passes/stripper.rs
src/llvm-project
src/rustdoc-json-types/Cargo.toml
src/test/assembly/x86_64-sse_crc.rs [new file with mode: 0644]
src/test/codegen-units/partitioning/extern-drop-glue.rs
src/test/codegen-units/partitioning/extern-generic.rs
src/test/codegen-units/partitioning/incremental-merging.rs
src/test/codegen-units/partitioning/inlining-from-extern-crate.rs
src/test/codegen-units/partitioning/local-drop-glue.rs
src/test/codegen-units/partitioning/local-generic.rs
src/test/codegen-units/partitioning/local-inlining-but-not-all.rs
src/test/codegen-units/partitioning/local-inlining.rs
src/test/codegen-units/partitioning/local-transitive-inlining.rs
src/test/codegen-units/partitioning/methods-are-with-self-type.rs
src/test/codegen-units/partitioning/regular-modules.rs
src/test/codegen-units/partitioning/shared-generics.rs
src/test/codegen-units/partitioning/statics.rs
src/test/codegen-units/partitioning/vtable-through-const.rs
src/test/codegen/panic-in-drop-abort.rs
src/test/codegen/sse42-implies-crc32.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-struct.rs
src/test/debuginfo/borrowed-tuple.rs
src/test/debuginfo/borrowed-unique-basic.rs
src/test/debuginfo/box.rs
src/test/debuginfo/boxed-struct.rs
src/test/debuginfo/closure-in-generic-function.rs
src/test/debuginfo/destructured-fn-argument.rs
src/test/debuginfo/destructured-for-loop-variable.rs
src/test/debuginfo/destructured-local.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/method-on-enum.rs
src/test/debuginfo/method-on-generic-struct.rs
src/test/debuginfo/method-on-struct.rs
src/test/debuginfo/method-on-trait.rs
src/test/debuginfo/method-on-tuple-struct.rs
src/test/debuginfo/msvc-scalarpair-params.rs [new file with mode: 0644]
src/test/debuginfo/mutex.rs
src/test/debuginfo/recursive-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/trait-pointers.rs
src/test/debuginfo/type-names.rs
src/test/debuginfo/unique-enum.rs
src/test/debuginfo/var-captured-in-nested-closure.rs
src/test/debuginfo/var-captured-in-sendable-closure.rs
src/test/debuginfo/var-captured-in-stack-closure.rs
src/test/incremental/hashes/extern_mods.rs
src/test/incremental/hashes/inherent_impls.rs
src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir
src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir
src/test/pretty/dollar-crate.pp
src/test/pretty/issue-4264.pp
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt
src/test/rustdoc/cross-crate-primitive-doc.rs
src/test/rustdoc/hidden-trait-methods-with-document-hidden-items.rs [new file with mode: 0644]
src/test/rustdoc/hidden-trait-methods.rs [new file with mode: 0644]
src/test/rustdoc/intra-doc/prim-methods-external-core.rs
src/test/rustdoc/macro-document-private-duplicate.rs
src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
src/test/ui-fulldeps/deriving-encodable-decodable-box.rs
src/test/ui/alignment-gep-tup-like-1.rs
src/test/ui/array-slice-vec/vec-dst.rs
src/test/ui/array-slice-vec/vector-no-ann-2.rs
src/test/ui/asm/aarch64/bad-options.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/bad-options.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/bad-reg.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/bad-reg.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/const.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/duplicate-options.fixed [new file with mode: 0644]
src/test/ui/asm/aarch64/duplicate-options.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/duplicate-options.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/interpolated-idents.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/interpolated-idents.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/parse-error.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/parse-error.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/srcloc.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/srcloc.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/sym.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/type-check-2.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/type-check-2.stderr [new file with mode: 0644]
src/test/ui/asm/aarch64/type-check-3.rs [new file with mode: 0644]
src/test/ui/asm/aarch64/type-check-3.stderr [new file with mode: 0644]
src/test/ui/asm/bad-options.rs [deleted file]
src/test/ui/asm/bad-options.stderr [deleted file]
src/test/ui/asm/bad-reg.rs [deleted file]
src/test/ui/asm/bad-reg.stderr [deleted file]
src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/asm/bad-template.mirunsafeck.stderr [deleted file]
src/test/ui/asm/bad-template.rs
src/test/ui/asm/bad-template.thirunsafeck.stderr [deleted file]
src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/asm/const.rs [deleted file]
src/test/ui/asm/duplicate-options.fixed [deleted file]
src/test/ui/asm/duplicate-options.rs [deleted file]
src/test/ui/asm/duplicate-options.stderr [deleted file]
src/test/ui/asm/interpolated-idents.rs [deleted file]
src/test/ui/asm/interpolated-idents.stderr [deleted file]
src/test/ui/asm/issue-72570.rs
src/test/ui/asm/issue-82869.rs [deleted file]
src/test/ui/asm/issue-82869.stderr [deleted file]
src/test/ui/asm/issue-87802.rs
src/test/ui/asm/issue-87802.stderr
src/test/ui/asm/naked-functions-ffi.rs
src/test/ui/asm/naked-functions-unused.aarch64.stderr [new file with mode: 0644]
src/test/ui/asm/naked-functions-unused.rs
src/test/ui/asm/naked-functions-unused.stderr [deleted file]
src/test/ui/asm/naked-functions-unused.x86_64.stderr [new file with mode: 0644]
src/test/ui/asm/naked-functions.rs
src/test/ui/asm/naked-functions.stderr
src/test/ui/asm/named-asm-labels.rs
src/test/ui/asm/named-asm-labels.stderr
src/test/ui/asm/noreturn.rs
src/test/ui/asm/parse-error.rs [deleted file]
src/test/ui/asm/parse-error.stderr [deleted file]
src/test/ui/asm/rustfix-asm.fixed
src/test/ui/asm/rustfix-asm.rs
src/test/ui/asm/srcloc.rs [deleted file]
src/test/ui/asm/srcloc.stderr [deleted file]
src/test/ui/asm/sym.rs [deleted file]
src/test/ui/asm/type-check-1.rs
src/test/ui/asm/type-check-1.stderr
src/test/ui/asm/type-check-2.rs [deleted file]
src/test/ui/asm/type-check-2.stderr [deleted file]
src/test/ui/asm/type-check-3.rs [deleted file]
src/test/ui/asm/type-check-3.stderr [deleted file]
src/test/ui/asm/type-check-4.rs
src/test/ui/asm/type-check-4.stderr
src/test/ui/asm/x86_64/bad-options.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/bad-options.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/bad-reg.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/bad-reg.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/const.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/duplicate-options.fixed [new file with mode: 0644]
src/test/ui/asm/x86_64/duplicate-options.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/duplicate-options.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/interpolated-idents.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/interpolated-idents.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/issue-82869.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/issue-82869.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/parse-error.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/parse-error.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/srcloc.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/srcloc.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/sym.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/type-check-2.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/type-check-2.stderr [new file with mode: 0644]
src/test/ui/asm/x86_64/type-check-3.rs [new file with mode: 0644]
src/test/ui/asm/x86_64/type-check-3.stderr [new file with mode: 0644]
src/test/ui/associated-type-bounds/traits-assoc-type-macros.rs
src/test/ui/associated-types/associated-types-doubleendediterator-object.rs
src/test/ui/async-await/issue-72442.rs
src/test/ui/async-await/issues/issue-64964.rs
src/test/ui/async-await/issues/issue-65159.rs
src/test/ui/async-await/issues/issue-65159.stderr
src/test/ui/attributes/extented-attribute-macro-error.rs [new file with mode: 0644]
src/test/ui/attributes/extented-attribute-macro-error.stderr [new file with mode: 0644]
src/test/ui/attributes/key-value-expansion.stderr
src/test/ui/attributes/register-attr-tool-fail.stderr
src/test/ui/autoderef-full-lval.rs
src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs
src/test/ui/autoref-autoderef/autoderef-method-priority.rs
src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs
src/test/ui/autoref-autoderef/autoderef-method-twice.rs
src/test/ui/autoref-autoderef/autoderef-method.rs
src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs
src/test/ui/binding/expr-match-generic-unique1.rs
src/test/ui/binding/expr-match-generic-unique2.rs
src/test/ui/binding/expr-match-unique.rs
src/test/ui/binding/func-arg-incomplete-pattern.rs
src/test/ui/binding/func-arg-ref-pattern.rs
src/test/ui/binding/let-assignability.rs
src/test/ui/binding/match-implicit-copy-unique.rs
src/test/ui/binding/match-unique-bind.rs
src/test/ui/binding/match-value-binding-in-guard-3291.rs
src/test/ui/borrowck/borrow-tuple-fields.rs
src/test/ui/borrowck/borrowck-bad-nested-calls-free.rs
src/test/ui/borrowck/borrowck-bad-nested-calls-move.rs
src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs
src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs
src/test/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.stderr
src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs
src/test/ui/borrowck/borrowck-box-sensitivity.rs
src/test/ui/borrowck/borrowck-closures-mut-and-imm.rs
src/test/ui/borrowck/borrowck-closures-two-mut-fail.rs
src/test/ui/borrowck/borrowck-closures-two-mut.rs
src/test/ui/borrowck/borrowck-closures-use-after-free.rs
src/test/ui/borrowck/borrowck-closures-use-after-free.stderr
src/test/ui/borrowck/borrowck-field-sensitivity-rpass.rs
src/test/ui/borrowck/borrowck-field-sensitivity.rs
src/test/ui/borrowck/borrowck-field-sensitivity.stderr
src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs
src/test/ui/borrowck/borrowck-issue-14498.rs
src/test/ui/borrowck/borrowck-issue-2657-1.rs
src/test/ui/borrowck/borrowck-issue-2657-2.rs
src/test/ui/borrowck/borrowck-lend-flow-if.rs
src/test/ui/borrowck/borrowck-lend-flow-loop.rs
src/test/ui/borrowck/borrowck-lend-flow-loop.stderr
src/test/ui/borrowck/borrowck-lend-flow.rs
src/test/ui/borrowck/borrowck-loan-blocks-move-cc.rs
src/test/ui/borrowck/borrowck-loan-blocks-move.rs
src/test/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs
src/test/ui/borrowck/borrowck-loan-blocks-mut-uniq.stderr
src/test/ui/borrowck/borrowck-loan-in-overloaded-op.rs
src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr
src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs
src/test/ui/borrowck/borrowck-move-by-capture-ok.rs
src/test/ui/borrowck/borrowck-move-by-capture.rs
src/test/ui/borrowck/borrowck-move-by-capture.stderr
src/test/ui/borrowck/borrowck-move-error-with-note.rs
src/test/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs
src/test/ui/borrowck/borrowck-move-moved-value-into-closure.rs
src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr
src/test/ui/borrowck/borrowck-move-subcomponent.rs
src/test/ui/borrowck/borrowck-multiple-captures.rs
src/test/ui/borrowck/borrowck-multiple-captures.stderr
src/test/ui/borrowck/borrowck-mut-uniq.rs
src/test/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs
src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs
src/test/ui/borrowck/borrowck-uniq-via-lend.rs
src/test/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
src/test/ui/borrowck/borrowck-use-mut-borrow.rs
src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
src/test/ui/borrowck/fsu-moves-and-copies.rs
src/test/ui/borrowck/issue-17263.rs
src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs
src/test/ui/class-cast-to-trait.rs
src/test/ui/cleanup-arm-conditional.rs
src/test/ui/cleanup-rvalue-scopes.rs
src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
src/test/ui/clone-with-exterior.rs
src/test/ui/close-over-big-then-small-data.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout [new file with mode: 0644]
src/test/ui/coercion/coerce-expect-unsized.rs
src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr [new file with mode: 0644]
src/test/ui/coercion/coerce-issue-49593-box-never.rs
src/test/ui/coherence/coherence-projection-conflict-orphan.stderr
src/test/ui/consts/issue-89088.rs [new file with mode: 0644]
src/test/ui/consts/miri_unleashed/box.rs
src/test/ui/consts/miri_unleashed/box.stderr
src/test/ui/consts/refs_check_const_eq-issue-88384.rs [new file with mode: 0644]
src/test/ui/consts/refs_check_const_eq-issue-88384.stderr [new file with mode: 0644]
src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs [new file with mode: 0644]
src/test/ui/crate-method-reexport-grrrrrrr.rs
src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs
src/test/ui/cross-crate/cci_borrow.rs
src/test/ui/dep-graph/dep-graph-assoc-type-codegen.rs
src/test/ui/dep-graph/dep-graph-assoc-type-codegen.stderr
src/test/ui/dep-graph/dep-graph-caller-callee.rs
src/test/ui/dep-graph/dep-graph-caller-callee.stderr
src/test/ui/dep-graph/dep-graph-struct-signature.rs
src/test/ui/dep-graph/dep-graph-struct-signature.stderr
src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs
src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr
src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.rs
src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr
src/test/ui/dep-graph/dep-graph-trait-impl.rs
src/test/ui/dep-graph/dep-graph-trait-impl.stderr
src/test/ui/dep-graph/dep-graph-type-alias.rs
src/test/ui/dep-graph/dep-graph-type-alias.stderr
src/test/ui/dep-graph/dep-graph-variance-alias.rs
src/test/ui/dep-graph/dep-graph-variance-alias.stderr
src/test/ui/deref.rs
src/test/ui/deriving/deriving-default-box.rs
src/test/ui/destructure-trait-ref.rs
src/test/ui/destructure-trait-ref.stderr
src/test/ui/drop/drop-on-empty-block-exit.rs
src/test/ui/drop/drop-struct-as-object.rs
src/test/ui/drop/drop-trait-enum.rs
src/test/ui/dynamically-sized-types/dst-trait-tuple.rs
src/test/ui/dynamically-sized-types/dst-tuple.rs
src/test/ui/expr-block-generic-unique1.rs
src/test/ui/expr-block-generic-unique2.rs
src/test/ui/expr-block-unique.rs
src/test/ui/expr-if-unique.rs
src/test/ui/feature-gates/feature-gate-closure_track_caller.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr [new file with mode: 0644]
src/test/ui/fn/fn-trait-formatting.rs
src/test/ui/fn/fn-trait-formatting.stderr
src/test/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs
src/test/ui/gated-bad-feature.stderr
src/test/ui/generic-associated-types/issue-88360.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/issue-88360.stderr [new file with mode: 0644]
src/test/ui/generics/generic-alias-unique.rs
src/test/ui/generics/generic-exterior-unique.rs
src/test/ui/generics/generic-fn-unique.rs
src/test/ui/generics/generic-object.rs
src/test/ui/generics/generic-recursive-tag.rs
src/test/ui/generics/generic-tag.rs
src/test/ui/generics/generic-unique.rs
src/test/ui/impl-trait/auto-trait-leak.stderr
src/test/ui/infinite/infinite-autoderef.rs
src/test/ui/infinite/infinite-autoderef.stderr
src/test/ui/init-res-into-things.rs
src/test/ui/intrinsics/intrinsic-atomics.rs
src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
src/test/ui/invalid/invalid-crate-type-macro.rs [new file with mode: 0644]
src/test/ui/invalid/invalid-crate-type-macro.stderr [new file with mode: 0644]
src/test/ui/invalid_crate_type_syntax.stderr
src/test/ui/kindck/kindck-impl-type-params-2.rs
src/test/ui/kindck/kindck-impl-type-params.rs
src/test/ui/kindck/kindck-inherited-copy-bound.rs
src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs [new file with mode: 0644]
src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr [new file with mode: 0644]
src/test/ui/lang-items/issue-83471.rs [new file with mode: 0644]
src/test/ui/lang-items/issue-83471.stderr [new file with mode: 0644]
src/test/ui/last-use-is-capture.rs
src/test/ui/leak-unique-as-tydesc.rs
src/test/ui/lint/issue-79546-fuel-ice.rs [new file with mode: 0644]
src/test/ui/lint/lint-malformed.stderr
src/test/ui/lint/lint-owned-heap-memory.rs
src/test/ui/lint/lint-owned-heap-memory.stderr
src/test/ui/lint/must_not_suspend/boxed.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/boxed.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/dedup.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/dedup.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/generic.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/handled.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/other_items.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/other_items.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/ref.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/ref.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/return.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/return.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/trait.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/trait.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/unit.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/unit.stderr [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/warn.rs [new file with mode: 0644]
src/test/ui/lint/must_not_suspend/warn.stderr [new file with mode: 0644]
src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs
src/test/ui/list.rs
src/test/ui/liveness/liveness-move-call-arg.rs
src/test/ui/liveness/liveness-move-call-arg.stderr
src/test/ui/liveness/liveness-move-in-loop.rs
src/test/ui/liveness/liveness-move-in-loop.stderr
src/test/ui/liveness/liveness-move-in-while.rs
src/test/ui/liveness/liveness-move-in-while.stderr
src/test/ui/liveness/liveness-use-after-move.rs
src/test/ui/liveness/liveness-use-after-move.stderr
src/test/ui/macros/bang-after-name.fixed [new file with mode: 0644]
src/test/ui/macros/bang-after-name.rs [new file with mode: 0644]
src/test/ui/macros/bang-after-name.stderr [new file with mode: 0644]
src/test/ui/malformed/malformed-plugin-1.stderr
src/test/ui/malformed/malformed-plugin-2.stderr
src/test/ui/map-types.rs
src/test/ui/methods/auxiliary/method_self_arg1.rs
src/test/ui/methods/auxiliary/method_self_arg2.rs
src/test/ui/methods/method-self-arg-aux1.rs
src/test/ui/methods/method-self-arg-aux2.rs
src/test/ui/methods/method-self-arg-trait.rs
src/test/ui/methods/method-self-arg.rs
src/test/ui/methods/method-two-trait-defer-resolution-2.rs
src/test/ui/modules/path-invalid-form.rs [new file with mode: 0644]
src/test/ui/modules/path-invalid-form.stderr [new file with mode: 0644]
src/test/ui/modules/path-macro.rs [new file with mode: 0644]
src/test/ui/modules/path-macro.stderr [new file with mode: 0644]
src/test/ui/moves/move-1-unique.rs
src/test/ui/moves/move-2-unique.rs
src/test/ui/moves/move-2.rs
src/test/ui/moves/move-3-unique.rs
src/test/ui/moves/move-4-unique.rs
src/test/ui/moves/move-4.rs
src/test/ui/moves/move-arg-2-unique.rs
src/test/ui/moves/move-arg-2.rs
src/test/ui/moves/move-guard-same-consts.rs
src/test/ui/moves/move-guard-same-consts.stderr
src/test/ui/moves/move-in-guard-1.rs
src/test/ui/moves/move-in-guard-1.stderr
src/test/ui/moves/move-in-guard-2.rs
src/test/ui/moves/move-in-guard-2.stderr
src/test/ui/moves/move-out-of-tuple-field.rs
src/test/ui/moves/moves-based-on-type-block-bad.rs
src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs
src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
src/test/ui/moves/moves-based-on-type-tuple.rs
src/test/ui/moves/moves-based-on-type-tuple.stderr
src/test/ui/moves/moves-sru-moved-field.rs
src/test/ui/mut-function-arguments.rs
src/test/ui/mut/mut-cross-borrowing.rs
src/test/ui/never_type/defaulted-never-note.fallback.stderr [new file with mode: 0644]
src/test/ui/never_type/defaulted-never-note.rs
src/test/ui/never_type/defaulted-never-note.stderr [deleted file]
src/test/ui/never_type/diverging-fallback-control-flow.rs
src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr [new file with mode: 0644]
src/test/ui/never_type/diverging-fallback-no-leak.rs [new file with mode: 0644]
src/test/ui/never_type/diverging-fallback-unconstrained-return.rs [new file with mode: 0644]
src/test/ui/never_type/fallback-closure-ret.rs [new file with mode: 0644]
src/test/ui/never_type/fallback-closure-wrap.fallback.stderr [new file with mode: 0644]
src/test/ui/never_type/fallback-closure-wrap.rs [new file with mode: 0644]
src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr [new file with mode: 0644]
src/test/ui/never_type/never-value-fallback-issue-66757.rs
src/test/ui/new-box-syntax.rs
src/test/ui/new-box.rs
src/test/ui/nll/issue-52663-trait-object.rs
src/test/ui/nll/issue-52663-trait-object.stderr
src/test/ui/no_crate_type.stderr
src/test/ui/nullable-pointer-iotareduction.rs
src/test/ui/objects-owned-object-borrowed-method-headerless.rs
src/test/ui/objects-owned-object-owned-method.rs
src/test/ui/occurs-check-2.rs
src/test/ui/occurs-check-2.stderr
src/test/ui/occurs-check.rs
src/test/ui/occurs-check.stderr
src/test/ui/output-slot-variants.rs
src/test/ui/overloaded/overloaded-autoderef.rs
src/test/ui/overloaded/overloaded-index-autoderef.rs
src/test/ui/panics/args-panic.rs
src/test/ui/panics/panic-macro-any.rs
src/test/ui/parser/issue-44406.stderr
src/test/ui/parser/issue-88770.rs [new file with mode: 0644]
src/test/ui/parser/issue-88770.stderr [new file with mode: 0644]
src/test/ui/parser/trailing-plus-in-bounds.rs
src/test/ui/parser/unicode-character-literal.fixed [new file with mode: 0644]
src/test/ui/parser/unicode-character-literal.rs [new file with mode: 0644]
src/test/ui/parser/unicode-character-literal.stderr [new file with mode: 0644]
src/test/ui/pattern/usefulness/issue-12116.rs
src/test/ui/pattern/usefulness/issue-12116.stderr
src/test/ui/pattern/usefulness/issue-3601.rs
src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs [deleted file]
src/test/ui/proc-macro/attribute-after-derive-feature-gate.stderr [deleted file]
src/test/ui/proc-macro/attribute-after-derive.rs
src/test/ui/proc-macro/attribute-after-derive.stdout
src/test/ui/pure-sum.rs
src/test/ui/rcvr-borrowed-to-region.rs
src/test/ui/reachable/expr_again.rs
src/test/ui/reachable/unreachable-arm.rs
src/test/ui/recursion/issue-26548-recursion-via-normalize.rs
src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr
src/test/ui/recursion_limit/invalid_digit_type.rs [new file with mode: 0644]
src/test/ui/recursion_limit/invalid_digit_type.stderr [new file with mode: 0644]
src/test/ui/recursion_limit/invalid_macro.rs [new file with mode: 0644]
src/test/ui/recursion_limit/invalid_macro.stderr [new file with mode: 0644]
src/test/ui/regions/issue-12470.rs
src/test/ui/regions/regions-borrow-at.rs
src/test/ui/regions/regions-borrow-uniq.rs
src/test/ui/regions/regions-close-associated-type-into-object.rs
src/test/ui/regions/regions-close-object-into-object-1.rs
src/test/ui/regions/regions-close-object-into-object-1.stderr
src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
src/test/ui/regions/regions-close-object-into-object-2.rs
src/test/ui/regions/regions-close-object-into-object-2.stderr
src/test/ui/regions/regions-close-object-into-object-3.rs
src/test/ui/regions/regions-close-object-into-object-3.stderr
src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
src/test/ui/regions/regions-close-object-into-object-4.rs
src/test/ui/regions/regions-close-object-into-object-4.stderr
src/test/ui/regions/regions-close-object-into-object-5.nll.stderr
src/test/ui/regions/regions-close-object-into-object-5.rs
src/test/ui/regions/regions-close-object-into-object-5.stderr
src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr
src/test/ui/regions/regions-close-over-type-parameter-1.rs
src/test/ui/regions/regions-close-over-type-parameter-1.stderr
src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr
src/test/ui/regions/regions-close-over-type-parameter-multiple.rs
src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
src/test/ui/regions/regions-close-over-type-parameter-successfully.rs
src/test/ui/regions/regions-dependent-addr-of.rs
src/test/ui/regions/regions-early-bound-trait-param.rs
src/test/ui/regions/regions-escape-into-other-fn.rs
src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs
src/test/ui/regions/regions-infer-borrow-scope.rs
src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs
src/test/ui/regions/regions-ref-in-fn-arg.rs
src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs
src/test/ui/regions/regions-trait-variance.rs
src/test/ui/rfc-2091-track-caller/tracked-closure.rs [new file with mode: 0644]
src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs
src/test/ui/self/explicit-self-generic.rs
src/test/ui/self/explicit-self-objects-uniq.rs
src/test/ui/self/explicit-self.rs
src/test/ui/self/self-impl-2.rs
src/test/ui/self/self-in-mut-slot-default-method.rs
src/test/ui/self/self-re-assign.rs
src/test/ui/self/ufcs-explicit-self.rs
src/test/ui/self/uniq-self-in-mut-slot.rs
src/test/ui/shadowed/shadowed-type-parameter.rs
src/test/ui/span/coerce-suggestions.rs
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/issue-11925.rs
src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs
src/test/ui/span/regions-close-over-type-parameter-2.rs
src/test/ui/static/static-region-bound.rs
src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs
src/test/ui/structs-enums/class-separate-impl.rs
src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs
src/test/ui/suggestions/issue-72766.rs
src/test/ui/suggestions/missing-type-param-used-in-param.fixed [new file with mode: 0644]
src/test/ui/suggestions/missing-type-param-used-in-param.rs [new file with mode: 0644]
src/test/ui/suggestions/missing-type-param-used-in-param.stderr [new file with mode: 0644]
src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs
src/test/ui/traits/bound/in-arc.rs
src/test/ui/traits/coercion.rs
src/test/ui/traits/conditional-dispatch.rs
src/test/ui/traits/issue-6128.rs
src/test/ui/traits/kindck-owned-contains-1.rs
src/test/ui/traits/object-one-type-two-traits.rs
src/test/ui/traits/object/generics.rs
src/test/ui/traits/test-2.rs
src/test/ui/traits/test-2.stderr
src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
src/test/ui/type-alias-impl-trait/bound_reduction2.rs
src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
src/test/ui/type-alias-impl-trait/incomplete-inference.rs
src/test/ui/type-alias-impl-trait/incomplete-inference.stderr
src/test/ui/type-alias-impl-trait/inference-cycle.stderr
src/test/ui/type-alias-impl-trait/issue-60371.rs
src/test/ui/type-alias-impl-trait/issue-60371.stderr
src/test/ui/type-alias-impl-trait/issue-60564.rs
src/test/ui/type-alias-impl-trait/issue-60564.stderr
src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs [new file with mode: 0644]
src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr [new file with mode: 0644]
src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
src/test/ui/type-param-constraints.rs
src/test/ui/typeclasses-eq-example-static.rs
src/test/ui/typeclasses-eq-example.rs
src/test/ui/ufcs/ufcs-explicit-self-bad.rs
src/test/ui/unboxed-closures/unboxed-closures-boxed.rs
src/test/ui/uninhabited/uninhabited-patterns.rs
src/test/ui/unique-object-noncopyable.rs
src/test/ui/unique/unique-assign-copy.rs
src/test/ui/unique/unique-assign-drop.rs
src/test/ui/unique/unique-assign-generic.rs
src/test/ui/unique/unique-assign.rs
src/test/ui/unique/unique-autoderef-field.rs
src/test/ui/unique/unique-autoderef-index.rs
src/test/ui/unique/unique-cmp.rs
src/test/ui/unique/unique-containing-tag.rs
src/test/ui/unique/unique-create.rs
src/test/ui/unique/unique-decl-init-copy.rs
src/test/ui/unique/unique-decl-init.rs
src/test/ui/unique/unique-decl-move.rs
src/test/ui/unique/unique-deref.rs
src/test/ui/unique/unique-destructure.rs
src/test/ui/unique/unique-drop-complex.rs
src/test/ui/unique/unique-fn-arg-move.rs
src/test/ui/unique/unique-fn-arg-mut.rs
src/test/ui/unique/unique-fn-arg.rs
src/test/ui/unique/unique-fn-ret.rs
src/test/ui/unique/unique-in-tag.rs
src/test/ui/unique/unique-in-vec-copy.rs
src/test/ui/unique/unique-in-vec.rs
src/test/ui/unique/unique-init.rs
src/test/ui/unique/unique-kinds.rs
src/test/ui/unique/unique-log.rs
src/test/ui/unique/unique-move-drop.rs
src/test/ui/unique/unique-move-temp.rs
src/test/ui/unique/unique-move.rs
src/test/ui/unique/unique-mutable.rs
src/test/ui/unique/unique-object-move.rs
src/test/ui/unique/unique-pat-2.rs
src/test/ui/unique/unique-pat-3.rs
src/test/ui/unique/unique-pat.rs
src/test/ui/unique/unique-rec.rs
src/test/ui/unique/unique-send-2.rs
src/test/ui/unique/unique-send.rs
src/test/ui/unique/unique-swap.rs
src/test/ui/unsized/unsized2.rs
src/test/ui/unsized/unsized3-rpass.rs
src/test/ui/unused-move-capture.rs
src/test/ui/unused-move.rs
src/test/ui/unwind-unique.rs
src/test/ui/use/use-after-move-implicity-coerced-object.rs
src/test/ui/use/use-after-move-implicity-coerced-object.stderr
src/test/ui/use/use-after-move-self.rs
src/test/ui/wf/hir-wf-check-erase-regions.rs
src/tools/build-manifest/Cargo.toml
src/tools/bump-stage0/Cargo.toml
src/tools/cargo
src/tools/cargotest/Cargo.toml
src/tools/clippy/clippy_lints/src/escape.rs
src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
src/tools/clippy/clippy_lints/src/methods/mod.rs
src/tools/clippy/clippy_utils/src/higher.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/common.rs
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/runtest.rs
src/tools/compiletest/src/util.rs
src/tools/error_index_generator/Cargo.toml
src/tools/expand-yaml-anchors/Cargo.toml
src/tools/html-checker/Cargo.toml
src/tools/jsondocck/Cargo.toml
src/tools/linkchecker/Cargo.toml
src/tools/lint-docs/Cargo.toml
src/tools/lint-docs/src/lib.rs
src/tools/remote-test-client/Cargo.toml
src/tools/remote-test-server/Cargo.toml
src/tools/rust-analyzer
src/tools/rust-demangler/Cargo.toml
src/tools/rustbook/Cargo.toml
src/tools/rustc-workspace-hack/Cargo.toml
src/tools/rustdoc-themes/Cargo.toml
src/tools/rustdoc/Cargo.toml
src/tools/rustfmt/Cargo.toml
src/tools/tidy/Cargo.toml
src/tools/tidy/src/edition.rs
src/tools/tier-check/Cargo.toml
src/tools/unicode-table-generator/Cargo.toml
src/tools/unstable-book-gen/Cargo.toml
src/tools/x/Cargo.toml

index 5917757ff3e2198635a549d4a2c0113b9cd18472..6b3a714920bb4938694beec3018b8f4ade2964ae 100644 (file)
@@ -882,9 +882,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.45+curl-7.78.0"
+version = "0.4.48+curl-7.79.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb"
+checksum = "a6a77a741f832116da66aeb126b4f19190ecf46144a74a9bde43c2086f38da0e"
 dependencies = [
  "cc",
  "libc",
index c0851a1506e130eb017b21334e7454ee23c89a04..ef1377a4a32dfe8abe45318ad38a563d0133abcf 100644 (file)
@@ -1,3 +1,188 @@
+Rust 1.56.0 (2021-10-21)
+========================
+
+Language
+--------
+
+- [The 2021 Edition is now stable.][rust#88100]
+  See [the edition guide][rust-2021-edition-guide] for more details.
+- [You can now specify explicit discriminant values on any Rust enum.][rust#86860]
+- [The pattern in `binding @ pattern` can now also introduce new bindings.][rust#85305]
+- [Union field access is permitted in `const fn`.][rust#85769]
+
+[rust-2021-edition-guide]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html
+
+Compiler
+--------
+
+- [Upgrade to LLVM 13.][rust#87570]
+- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.][rust#88023]
+- [Allow specifying a deployment target version for all iOS targets][rust#87699]
+- [Warnings can be forced on with `--force-warn`.][rust#87472]
+  This feature is primarily intended for usage by `cargo fix`, rather than end users.
+- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760]
+- [Add `powerpc-unknown-freebsd` at Tier 3\*.][rust#87370]
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+information on Rust's tiered platform support.
+
+Libraries
+---------
+
+- [Allow writing of incomplete UTF-8 sequences via stdout/stderr on Windows.][rust#83342]
+  The Windows console still requires valid Unicode, but this change allows
+  splitting a UTF-8 character across multiple write calls. This allows, for
+  instance, programs that just read and write data buffers (e.g. copying a file
+  to stdout) without regard for Unicode or character boundaries.
+- [Prefer `AtomicU{64,128}` over Mutex for Instant backsliding protection.][rust#83093]
+  For this use case, atomics scale much better under contention.
+- [Implement `Extend<(A, B)>` for `(Extend<A>, Extend<B>)`][rust#85835]
+- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
+- [`impl From<[(K, V); N]>` for all collections.][rust#84111]
+- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
+- [Treat invalid environment variable names as non-existent.][rust#86183]
+  Previously, the environment functions would panic if given a variable name
+  with an internal null character or equal sign (`=`). Now, these functions will
+  just treat such names as non-existent variables, since the OS cannot represent
+  the existence of a variable with such a name.
+
+Stabilised APIs
+---------------
+
+- [`std::os::unix::fs::chroot`]
+- [`Iterator::intersperse`]
+- [`Iterator::intersperse_with`]
+- [`UnsafeCell::raw_get`]
+- [`BufWriter::into_parts`]
+- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]
+  These APIs were previously stable in `std`, but are now also available in `core`.
+- [`Vec::shrink_to`]
+- [`String::shrink_to`]
+- [`OsString::shrink_to`]
+- [`PathBuf::shrink_to`]
+- [`BinaryHeap::shrink_to`]
+- [`VecDeque::shrink_to`]
+- [`HashMap::shrink_to`]
+- [`HashSet::shrink_to`]
+- [`task::ready!`]
+
+These APIs are now usable in const contexts:
+
+- [`std::mem::transmute`]
+- [`[T]::first`][`slice::first`]
+- [`[T]::split_first`][`slice::split_first`]
+- [`[T]::last`][`slice::last`]
+- [`[T]::split_last`][`slice::split_last`]
+
+Cargo
+-----
+
+- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`]
+  This has no effect at present on dependency version selection.
+  We encourage crates to specify their minimum supported Rust version, and we encourage CI systems
+  that support Rust code to include a crate's specified minimum version in the text matrix for that
+  crate by default.
+
+Compatibility notes
+-------------------
+
+- [Update to new argument parsing rules on Windows.][rust#87580]
+  This adjusts Rust's standard library to match the behavior of the standard
+  libraries for C/C++. The rules have changed slightly over time, and this PR
+  brings us to the latest set of rules (changed in 2008).
+- [Disallow the aapcs calling convention on aarch64][rust#88399]
+  This was already not supported by LLVM; this change surfaces this lack of
+  support with a better error message.
+- [Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default][rust#87385]
+- [Warn when an escaped newline skips multiple lines.][rust#87671]
+- [Calls to `libc::getpid` / `std::process::id` from `Command::pre_exec`
+   may return different values on glibc <= 2.24.][rust#81825]
+   Rust now invokes the `clone3` system call directly, when available, to use new functionality
+   available via that system call. Older versions of glibc cache the result of `getpid`, and only
+   update that cache when calling glibc's clone/fork functions, so a direct system call bypasses
+   that cache update. glibc 2.25 and newer no longer cache `getpid` for exactly this reason.
+
+Internal changes
+----------------
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+- [LLVM is compiled with PGO in published x86_64-unknown-linux-gnu artifacts.][rust#88069]
+  This improves the performance of most Rust builds.
+- [Unify representation of macros in internal data structures.][rust#88019]
+  This change fixes a host of bugs with the handling of macros by the compiler,
+  as well as rustdoc.
+
+[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
+[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
+[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
+[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
+[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
+[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
+[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
+[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
+[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
+[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
+[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
+[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
+[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
+[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
+[`task::ready!`]: https://doc.rust-lang.org/stable/std/task/macro.ready.html
+[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
+[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
+[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
+[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last
+[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last
+[`rust-version`]: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
+[rust#87671]: https://github.com/rust-lang/rust/pull/87671
+[rust#86183]: https://github.com/rust-lang/rust/pull/86183
+[rust#87385]: https://github.com/rust-lang/rust/pull/87385
+[rust#88100]: https://github.com/rust-lang/rust/pull/88100
+[rust#86860]: https://github.com/rust-lang/rust/pull/86860
+[rust#84039]: https://github.com/rust-lang/rust/pull/84039
+[rust#86492]: https://github.com/rust-lang/rust/pull/86492
+[rust#88363]: https://github.com/rust-lang/rust/pull/88363
+[rust#85305]: https://github.com/rust-lang/rust/pull/85305
+[rust#87832]: https://github.com/rust-lang/rust/pull/87832
+[rust#88069]: https://github.com/rust-lang/rust/pull/88069
+[rust#87472]: https://github.com/rust-lang/rust/pull/87472
+[rust#87699]: https://github.com/rust-lang/rust/pull/87699
+[rust#87570]: https://github.com/rust-lang/rust/pull/87570
+[rust#88023]: https://github.com/rust-lang/rust/pull/88023
+[rust#87760]: https://github.com/rust-lang/rust/pull/87760
+[rust#87370]: https://github.com/rust-lang/rust/pull/87370
+[rust#87580]: https://github.com/rust-lang/rust/pull/87580
+[rust#83342]: https://github.com/rust-lang/rust/pull/83342
+[rust#83093]: https://github.com/rust-lang/rust/pull/83093
+[rust#88177]: https://github.com/rust-lang/rust/pull/88177
+[rust#88548]: https://github.com/rust-lang/rust/pull/88548
+[rust#88551]: https://github.com/rust-lang/rust/pull/88551
+[rust#88299]: https://github.com/rust-lang/rust/pull/88299
+[rust#88220]: https://github.com/rust-lang/rust/pull/88220
+[rust#85835]: https://github.com/rust-lang/rust/pull/85835
+[rust#86879]: https://github.com/rust-lang/rust/pull/86879
+[rust#86744]: https://github.com/rust-lang/rust/pull/86744
+[rust#84662]: https://github.com/rust-lang/rust/pull/84662
+[rust#86593]: https://github.com/rust-lang/rust/pull/86593
+[rust#81050]: https://github.com/rust-lang/rust/pull/81050
+[rust#81363]: https://github.com/rust-lang/rust/pull/81363
+[rust#84111]: https://github.com/rust-lang/rust/pull/84111
+[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
+[rust#88490]: https://github.com/rust-lang/rust/pull/88490
+[rust#88269]: https://github.com/rust-lang/rust/pull/88269
+[rust#84176]: https://github.com/rust-lang/rust/pull/84176
+[rust#88399]: https://github.com/rust-lang/rust/pull/88399
+[rust#88227]: https://github.com/rust-lang/rust/pull/88227
+[rust#88200]: https://github.com/rust-lang/rust/pull/88200
+[rust#82776]: https://github.com/rust-lang/rust/pull/82776
+[rust#88077]: https://github.com/rust-lang/rust/pull/88077
+[rust#87728]: https://github.com/rust-lang/rust/pull/87728
+[rust#87050]: https://github.com/rust-lang/rust/pull/87050
+[rust#87619]: https://github.com/rust-lang/rust/pull/87619
+[rust#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918
+[rust#88019]: https://github.com/rust-lang/rust/pull/88019
+
 Version 1.55.0 (2021-09-09)
 ============================
 
@@ -4985,7 +5170,7 @@ Libraries
 - [Upgrade to Unicode 10.0.0][42999]
 - [Reimplemented `{f32, f64}::{min, max}` in Rust instead of using CMath.][42430]
 - [Skip the main thread's manual stack guard on Linux][43072]
-- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in O(1) time][43077]
+- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in *O*(1) time][43077]
 - [`#[repr(align(N))]` attribute max number is now 2^31 - 1.][43097] This was
   previously 2^15.
 - [`{OsStr, Path}::Display` now avoids allocations where possible][42613]
@@ -8288,7 +8473,7 @@ Libraries
   algorithm][s].
 * [`std::io::copy` allows `?Sized` arguments][cc].
 * The `Windows`, `Chunks`, and `ChunksMut` iterators over slices all
-  [override `count`, `nth` and `last` with an O(1)
+  [override `count`, `nth` and `last` with an *O*(1)
   implementation][it].
 * [`Default` is implemented for arrays up to `[T; 32]`][d].
 * [`IntoRawFd` has been added to the Unix-specific prelude,
@@ -8810,7 +8995,7 @@ Libraries
 * The `Default` implementation for `Arc` [no longer requires `Sync +
   Send`][arc].
 * [The `Iterator` methods `count`, `nth`, and `last` have been
-  overridden for slices to have O(1) performance instead of O(n)][si].
+  overridden for slices to have *O*(1) performance instead of *O*(*n*)][si].
 * Incorrect handling of paths on Windows has been improved in both the
   compiler and the standard library.
 * [`AtomicPtr` gained a `Default` implementation][ap].
index 37f90bf3c10088114deeac862538937f5ce3e881..277cf0f51d378afa6df85ec3fcbdf4f3a1f16a37 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc-main"
 version = "0.0.0"
-edition = '2018'
+edition = "2021"
 
 [dependencies]
 rustc_driver = { path = "../rustc_driver" }
index 9f266b1fb978d04b05f1e99f3c5fe7f55b300e7e..bb01d4f51b899d8e1329668951d53f59fa87ea9a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_apfloat"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 bitflags = "1.2.1"
index eba8a2a082f3ea4a72d7e62a8fedec1f470e7ade..33ccd0445030f7e0f315a2cee1b409a65ef9f142 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_arena"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 rustc_data_structures = { path = "../rustc_data_structures" }
index 67cf5d92b00cb7052e1d05f9b0840d0bca54a631..58b967a370415741c3f0ba94c5cd1af099070006 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_ast"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 4e848a6a2b8fb2ffc4f003b88795dc1c915d2766..f4859ee4ae91f48133fe8684de01436d86dcb416 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_ast_lowering"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index ac7145bed7825d790ee6650eeddaae050d376588..a6ea4aa8923cfad252d7a96bdb11359f5c8256d3 100644 (file)
@@ -55,7 +55,6 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                         0,
                         ParenthesizedGenericArgs::Err,
                         ImplTraitContext::disallowed(),
-                        None,
                     ));
                     let args = self.lower_exprs(args);
                     hir::ExprKind::MethodCall(
@@ -328,7 +327,7 @@ fn lower_legacy_const_generics(
         let mut generic_args = vec![];
         for (idx, arg) in args.into_iter().enumerate() {
             if legacy_args_idx.contains(&idx) {
-                let parent_def_id = self.current_hir_id_owner.0;
+                let parent_def_id = self.current_hir_id_owner;
                 let node_id = self.resolver.next_node_id();
 
                 // Add a definition for the in-band const def.
index 980036c662ae56c72d2e4fecdfa827e4a72496b6..9f879494d7374ff574afb02f34f18597744cb89b 100644 (file)
@@ -40,12 +40,9 @@ fn with_trait_impl_ref<T>(
 
 impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
     fn visit_item(&mut self, item: &'a Item) {
-        self.lctx.allocate_hir_id_counter(item.id);
         let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| {
-            lctx.without_in_scope_lifetime_defs(|lctx| {
-                let hir_item = lctx.lower_item(item);
-                lctx.insert_item(hir_item)
-            })
+            let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item));
+            hir::OwnerNode::Item(node)
         });
 
         self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
@@ -72,26 +69,17 @@ fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) {
     }
 
     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
-        self.lctx.allocate_hir_id_counter(item.id);
         self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
-            AssocCtxt::Trait => {
-                let hir_item = lctx.lower_trait_item(item);
-                lctx.insert_trait_item(hir_item);
-            }
-            AssocCtxt::Impl => {
-                let hir_item = lctx.lower_impl_item(item);
-                lctx.insert_impl_item(hir_item);
-            }
+            AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
+            AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
         });
 
         visit::walk_assoc_item(self, item, ctxt);
     }
 
     fn visit_foreign_item(&mut self, item: &'a ForeignItem) {
-        self.lctx.allocate_hir_id_counter(item.id);
         self.lctx.with_hir_id_owner(item.id, |lctx| {
-            let hir_item = lctx.lower_foreign_item(item);
-            lctx.insert_foreign_item(hir_item);
+            hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
         });
 
         visit::walk_foreign_item(self, item);
@@ -106,12 +94,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
     // only used when lowering a child item of a trait or impl.
     fn with_parent_item_lifetime_defs<T>(
         &mut self,
-        parent_hir_id: hir::ItemId,
+        parent_hir_id: LocalDefId,
         f: impl FnOnce(&mut Self) -> T,
     ) -> T {
         let old_len = self.in_scope_lifetimes.len();
 
-        let parent_generics = match self.owners[parent_hir_id.def_id].unwrap().expect_item().kind {
+        let parent_generics = match self.owners[parent_hir_id].unwrap().expect_item().kind {
             hir::ItemKind::Impl(hir::Impl { ref generics, .. })
             | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
             _ => &[],
@@ -186,19 +174,20 @@ fn lower_item_id_use_tree(
         }
     }
 
-    pub fn lower_item(&mut self, i: &Item) -> hir::Item<'hir> {
+    fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
         let mut ident = i.ident;
-        let mut vis = self.lower_visibility(&i.vis, None);
+        let mut vis = self.lower_visibility(&i.vis);
         let hir_id = self.lower_node_id(i.id);
         let attrs = self.lower_attrs(hir_id, &i.attrs);
         let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
-        hir::Item {
+        let item = hir::Item {
             def_id: hir_id.expect_owner(),
             ident: self.lower_ident(ident),
             kind,
             vis,
             span: self.lower_span(i.span),
-        }
+        };
+        self.arena.alloc(item)
     }
 
     fn lower_item_kind(
@@ -480,10 +469,17 @@ fn lower_use_tree(
                 // Essentially a single `use` which imports two names is desugared into
                 // two imports.
                 for new_node_id in [id1, id2] {
-                    // Associate an HirId to both ids even if there is no resolution.
-                    let new_id = self.allocate_hir_id_counter(new_node_id);
-
-                    let res = if let Some(res) = resolutions.next() { res } else { continue };
+                    let new_id = self.resolver.local_def_id(new_node_id);
+                    let res = if let Some(res) = resolutions.next() {
+                        res
+                    } else {
+                        // Associate an HirId to both ids even if there is no resolution.
+                        let _old = self
+                            .node_id_to_hir_id
+                            .insert(new_node_id, hir::HirId::make_owner(new_id));
+                        debug_assert!(_old.is_none());
+                        continue;
+                    };
                     let ident = *ident;
                     let mut path = path.clone();
                     for seg in &mut path.segments {
@@ -493,24 +489,25 @@ fn lower_use_tree(
 
                     self.with_hir_id_owner(new_node_id, |this| {
                         let res = this.lower_res(res);
-                        let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
+                        let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
                         let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
                         let vis = this.rebuild_vis(&vis);
                         if let Some(attrs) = attrs {
                             this.attrs.insert(hir::HirId::make_owner(new_id), attrs);
                         }
 
-                        this.insert_item(hir::Item {
+                        let item = hir::Item {
                             def_id: new_id,
                             ident: this.lower_ident(ident),
                             kind,
                             vis,
                             span: this.lower_span(span),
-                        });
+                        };
+                        hir::OwnerNode::Item(this.arena.alloc(item))
                     });
                 }
 
-                let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None);
+                let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
                 hir::ItemKind::Use(path, hir::UseKind::Single)
             }
             UseTreeKind::Glob => {
@@ -550,7 +547,7 @@ fn lower_use_tree(
 
                 // Add all the nested `PathListItem`s to the HIR.
                 for &(ref use_tree, id) in trees {
-                    let new_hir_id = self.allocate_hir_id_counter(id);
+                    let new_hir_id = self.resolver.local_def_id(id);
 
                     let mut prefix = prefix.clone();
 
@@ -574,13 +571,14 @@ fn lower_use_tree(
                             this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs);
                         }
 
-                        this.insert_item(hir::Item {
+                        let item = hir::Item {
                             def_id: new_hir_id,
                             ident: this.lower_ident(ident),
                             kind,
                             vis,
                             span: this.lower_span(use_tree.span),
-                        });
+                        };
+                        hir::OwnerNode::Item(this.arena.alloc(item))
                     });
                 }
 
@@ -610,7 +608,7 @@ fn lower_use_tree(
 
                 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
                 let res = self.lower_res(res);
-                let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit, None);
+                let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
             }
         }
@@ -647,11 +645,11 @@ fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir>
         respan(self.lower_span(vis.span), vis_kind)
     }
 
-    fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
+    fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
         let def_id = hir_id.expect_owner();
         self.lower_attrs(hir_id, &i.attrs);
-        hir::ForeignItem {
+        let item = hir::ForeignItem {
             def_id,
             ident: self.lower_ident(i.ident),
             kind: match i.kind {
@@ -679,17 +677,17 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
                 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
             },
-            vis: self.lower_visibility(&i.vis, None),
+            vis: self.lower_visibility(&i.vis),
             span: self.lower_span(i.span),
-        }
+        };
+        self.arena.alloc(item)
     }
 
-    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
+    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
         hir::ForeignItemRef {
-            id: hir::ForeignItemId { def_id: self.allocate_hir_id_counter(i.id) },
+            id: hir::ForeignItemId { def_id: self.resolver.local_def_id(i.id) },
             ident: self.lower_ident(i.ident),
             span: self.lower_span(i.span),
-            vis: self.lower_visibility(&i.vis, Some(i.id)),
         }
     }
 
@@ -757,12 +755,12 @@ fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'
                 // FIXME(jseyfried): positional field hygiene.
                 None => Ident::new(sym::integer(index), self.lower_span(f.span)),
             },
-            vis: self.lower_visibility(&f.vis, None),
+            vis: self.lower_visibility(&f.vis),
             ty,
         }
     }
 
-    fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
+    fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
         let trait_item_def_id = hir_id.expect_owner();
 
@@ -805,13 +803,14 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
         };
 
         self.lower_attrs(hir_id, &i.attrs);
-        hir::TraitItem {
+        let item = hir::TraitItem {
             def_id: trait_item_def_id,
             ident: self.lower_ident(i.ident),
             generics,
             kind,
             span: self.lower_span(i.span),
-        }
+        };
+        self.arena.alloc(item)
     }
 
     fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
@@ -841,7 +840,7 @@ fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
         self.expr(span, hir::ExprKind::Err, AttrVec::new())
     }
 
-    fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> {
+    fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
         let impl_item_def_id = self.resolver.local_def_id(i.id);
 
         let (generics, kind) = match &i.kind {
@@ -895,26 +894,26 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> {
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
         let hir_id = self.lower_node_id(i.id);
         self.lower_attrs(hir_id, &i.attrs);
-        hir::ImplItem {
+        let item = hir::ImplItem {
             def_id: hir_id.expect_owner(),
             ident: self.lower_ident(i.ident),
             generics,
-            vis: self.lower_visibility(&i.vis, None),
+            vis: self.lower_visibility(&i.vis),
             defaultness,
             kind,
             span: self.lower_span(i.span),
-        }
+        };
+        self.arena.alloc(item)
     }
 
-    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> {
+    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
         // Since `default impl` is not yet implemented, this is always true in impls.
         let has_value = true;
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
         hir::ImplItemRef {
-            id: hir::ImplItemId { def_id: self.allocate_hir_id_counter(i.id) },
+            id: hir::ImplItemId { def_id: self.resolver.local_def_id(i.id) },
             ident: self.lower_ident(i.ident),
             span: self.lower_span(i.span),
-            vis: self.lower_visibility(&i.vis, Some(i.id)),
             defaultness,
             kind: match &i.kind {
                 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
@@ -932,25 +931,15 @@ fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> {
     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
     /// lower a `Visibility` value although we haven't lowered the owning
     /// `ImplItem` in question yet.
-    fn lower_visibility(
-        &mut self,
-        v: &Visibility,
-        explicit_owner: Option<NodeId>,
-    ) -> hir::Visibility<'hir> {
+    fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> {
         let node = match v.kind {
             VisibilityKind::Public => hir::VisibilityKind::Public,
             VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
             VisibilityKind::Restricted { ref path, id } => {
                 debug!("lower_visibility: restricted path id = {:?}", id);
-                let lowered_id = if let Some(owner) = explicit_owner {
-                    self.lower_node_id_with_owner(id, owner)
-                } else {
-                    self.lower_node_id(id)
-                };
-                let res = self.expect_full_res(id);
-                let res = self.lower_res(res);
+                let lowered_id = self.lower_node_id(id);
                 hir::VisibilityKind::Restricted {
-                    path: self.lower_path_extra(res, path, ParamMode::Explicit, explicit_owner),
+                    path: self.lower_path(id, path, ParamMode::Explicit),
                     hir_id: lowered_id,
                 }
             }
index 66bcd698e6a086d6971e8d8662e1a98239cf1122..3c75089a760f32fb9cc74c78391d8b32cc7fabac 100644 (file)
@@ -80,8 +80,6 @@ macro_rules! arena_vec {
 mod pat;
 mod path;
 
-const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
-
 rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
 
 struct LoweringContext<'a, 'hir: 'a> {
@@ -150,8 +148,8 @@ struct LoweringContext<'a, 'hir: 'a> {
     /// vector.
     in_scope_lifetimes: Vec<ParamName>,
 
-    current_hir_id_owner: (LocalDefId, u32),
-    item_local_id_counters: NodeMap<u32>,
+    current_hir_id_owner: LocalDefId,
+    item_local_id_counter: hir::ItemLocalId,
     node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
 
     allow_try_trait: Option<Lrc<[Symbol]>>,
@@ -330,8 +328,8 @@ pub fn lower_crate<'a, 'hir>(
         is_in_trait_impl: false,
         is_in_dyn_type: false,
         anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
-        current_hir_id_owner: (CRATE_DEF_ID, 0),
-        item_local_id_counters: Default::default(),
+        current_hir_id_owner: CRATE_DEF_ID,
+        item_local_id_counter: hir::ItemLocalId::new(0),
         node_id_to_hir_id: IndexVec::new(),
         generator_kind: None,
         task_context: None,
@@ -412,15 +410,15 @@ enum AnonymousLifetimeMode {
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
-        self.lower_node_id(CRATE_NODE_ID);
-        debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));
+        debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
 
         visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
 
-        let module = self.arena.alloc(self.lower_mod(&c.items, c.span));
-        self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
-        self.owners.ensure_contains_elem(CRATE_DEF_ID, || None);
-        self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module));
+        self.with_hir_id_owner(CRATE_NODE_ID, |lctx| {
+            let module = lctx.lower_mod(&c.items, c.span);
+            lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
+            hir::OwnerNode::Crate(lctx.arena.alloc(module))
+        });
 
         let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
         for (k, v) in self.resolver.take_trait_map().into_iter() {
@@ -456,47 +454,6 @@ fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
         self.arena.alloc(krate)
     }
 
-    fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {
-        let id = item.item_id();
-        let item = self.arena.alloc(item);
-        self.owners.ensure_contains_elem(id.def_id, || None);
-        self.owners[id.def_id] = Some(hir::OwnerNode::Item(item));
-        id
-    }
-
-    fn insert_foreign_item(&mut self, item: hir::ForeignItem<'hir>) -> hir::ForeignItemId {
-        let id = item.foreign_item_id();
-        let item = self.arena.alloc(item);
-        self.owners.ensure_contains_elem(id.def_id, || None);
-        self.owners[id.def_id] = Some(hir::OwnerNode::ForeignItem(item));
-        id
-    }
-
-    fn insert_impl_item(&mut self, item: hir::ImplItem<'hir>) -> hir::ImplItemId {
-        let id = item.impl_item_id();
-        let item = self.arena.alloc(item);
-        self.owners.ensure_contains_elem(id.def_id, || None);
-        self.owners[id.def_id] = Some(hir::OwnerNode::ImplItem(item));
-        id
-    }
-
-    fn insert_trait_item(&mut self, item: hir::TraitItem<'hir>) -> hir::TraitItemId {
-        let id = item.trait_item_id();
-        let item = self.arena.alloc(item);
-        self.owners.ensure_contains_elem(id.def_id, || None);
-        self.owners[id.def_id] = Some(hir::OwnerNode::TraitItem(item));
-        id
-    }
-
-    fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LocalDefId {
-        // Set up the counter if needed.
-        self.item_local_id_counters.entry(owner).or_insert(0);
-        // Always allocate the first `HirId` for the owner itself.
-        let lowered = self.lower_node_id_with_owner(owner, owner);
-        debug_assert_eq!(lowered.local_id.as_u32(), 0);
-        lowered.owner
-    }
-
     fn create_stable_hashing_context(&self) -> LoweringHasher<'_> {
         LoweringHasher {
             source_map: CachingSourceMapView::new(self.sess.source_map()),
@@ -504,47 +461,30 @@ fn create_stable_hashing_context(&self) -> LoweringHasher<'_> {
         }
     }
 
-    fn lower_node_id_generic(
+    fn with_hir_id_owner(
         &mut self,
-        ast_node_id: NodeId,
-        alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId,
-    ) -> hir::HirId {
-        assert_ne!(ast_node_id, DUMMY_NODE_ID);
-
-        let min_size = ast_node_id.as_usize() + 1;
+        owner: NodeId,
+        f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
+    ) -> LocalDefId {
+        let def_id = self.resolver.local_def_id(owner);
 
-        if min_size > self.node_id_to_hir_id.len() {
-            self.node_id_to_hir_id.resize(min_size, None);
-        }
+        // Always allocate the first `HirId` for the owner itself.
+        let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
+        debug_assert_eq!(_old, None);
 
-        if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
-            existing_hir_id
-        } else {
-            // Generate a new `HirId`.
-            let hir_id = alloc_hir_id(self);
-            self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
+        let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
+        let current_local_counter =
+            std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
 
-            hir_id
-        }
-    }
+        let item = f(self);
 
-    fn with_hir_id_owner<T>(&mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
-        let counter = self
-            .item_local_id_counters
-            .insert(owner, HIR_ID_COUNTER_LOCKED)
-            .unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner));
-        let def_id = self.resolver.local_def_id(owner);
-        let old_owner = std::mem::replace(&mut self.current_hir_id_owner, (def_id, counter));
-        let ret = f(self);
-        let (new_def_id, new_counter) =
-            std::mem::replace(&mut self.current_hir_id_owner, old_owner);
+        self.current_hir_id_owner = current_owner;
+        self.item_local_id_counter = current_local_counter;
 
-        debug_assert!(def_id == new_def_id);
-        debug_assert!(new_counter >= counter);
+        let _old = self.owners.insert(def_id, item);
+        debug_assert!(_old.is_none());
 
-        let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
-        debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
-        ret
+        def_id
     }
 
     /// This method allocates a new `HirId` for the given `NodeId` and stores it in
@@ -554,34 +494,14 @@ fn with_hir_id_owner<T>(&mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> T
     /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
     /// properly. Calling the method twice with the same `NodeId` is fine though.
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
-        self.lower_node_id_generic(ast_node_id, |this| {
-            let &mut (owner, ref mut local_id_counter) = &mut this.current_hir_id_owner;
-            let local_id = *local_id_counter;
-            *local_id_counter += 1;
-            hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
-        })
-    }
-
-    fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> hir::HirId {
-        self.lower_node_id_generic(ast_node_id, |this| {
-            let local_id_counter = this
-                .item_local_id_counters
-                .get_mut(&owner)
-                .expect("called `lower_node_id_with_owner` before `allocate_hir_id_counter`");
-            let local_id = *local_id_counter;
-
-            // We want to be sure not to modify the counter in the map while it
-            // is also on the stack. Otherwise we'll get lost updates when writing
-            // back from the stack to the map.
-            debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
-
-            *local_id_counter += 1;
-            let owner = this.resolver.opt_local_def_id(owner).expect(
-                "you forgot to call `create_def` or are lowering node-IDs \
-                 that do not belong to the current owner",
-            );
+        assert_ne!(ast_node_id, DUMMY_NODE_ID);
 
-            hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
+        *self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
+            // Generate a new `HirId`.
+            let owner = self.current_hir_id_owner;
+            let local_id = self.item_local_id_counter;
+            self.item_local_id_counter.increment_by(1);
+            hir::HirId { owner, local_id }
         })
     }
 
@@ -592,7 +512,7 @@ fn next_id(&mut self) -> hir::HirId {
 
     fn lower_res(&mut self, res: Res<NodeId>) -> Res {
         res.map_id(|id| {
-            self.lower_node_id_generic(id, |_| {
+            self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| {
                 panic!("expected `NodeId` to be lowered already for res {:#?}", res);
             })
         })
@@ -655,7 +575,7 @@ fn with_anonymous_lifetime_mode<R>(
     /// Mark a span as relative to the current owning item.
     fn lower_span(&self, span: Span) -> Span {
         if self.sess.opts.debugging_opts.incremental_relative_spans {
-            span.with_parent(Some(self.current_hir_id_owner.0))
+            span.with_parent(Some(self.current_hir_id_owner))
         } else {
             // Do not make spans relative when not using incremental compilation.
             span
@@ -828,7 +748,7 @@ fn add_in_band_defs<T>(
                     // wouldn't have been added yet.
                     let generics = this.lower_generics_mut(
                         generics,
-                        ImplTraitContext::Universal(&mut params, this.current_hir_id_owner.0),
+                        ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
                     );
                     let res = f(this, &mut params);
                     (params, (generics, res))
@@ -1034,7 +954,7 @@ fn lower_assoc_ty_constraint(
             }
             AssocTyConstraintKind::Bound { ref bounds } => {
                 let mut capturable_lifetimes;
-                let mut parent_def_id = self.current_hir_id_owner.0;
+                let mut parent_def_id = self.current_hir_id_owner;
                 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
                 let (desugar_to_impl_trait, itctx) = match itctx {
                     // We are in the return position:
@@ -1162,7 +1082,7 @@ fn lower_generic_arg(
 
                                 // Construct an AnonConst where the expr is the "ty"'s path.
 
-                                let parent_def_id = self.current_hir_id_owner.0;
+                                let parent_def_id = self.current_hir_id_owner;
                                 let node_id = self.resolver.next_node_id();
 
                                 // Add a definition for the in-band const def.
@@ -1428,12 +1348,13 @@ fn lower_opaque_impl_trait(
         // frequently opened issues show.
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
 
-        let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id);
+        let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
 
-        let collected_lifetimes = self.with_hir_id_owner(opaque_ty_node_id, move |lctx| {
+        let mut collected_lifetimes = Vec::new();
+        self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
             let hir_bounds = lower_bounds(lctx);
 
-            let collected_lifetimes = lifetimes_from_impl_trait_bounds(
+            collected_lifetimes = lifetimes_from_impl_trait_bounds(
                 opaque_ty_node_id,
                 &hir_bounds,
                 capturable_lifetimes,
@@ -1486,9 +1407,7 @@ fn lower_opaque_impl_trait(
             };
 
             trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
-            lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
-
-            collected_lifetimes
+            lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
         });
 
         let lifetimes =
@@ -1510,7 +1429,7 @@ fn generate_opaque_type(
         opaque_ty_item: hir::OpaqueTy<'hir>,
         span: Span,
         opaque_ty_span: Span,
-    ) {
+    ) -> hir::OwnerNode<'hir> {
         let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
         // Generate an `type Foo = impl Trait;` declaration.
         trace!("registering opaque type with id {:#?}", opaque_ty_id);
@@ -1521,11 +1440,7 @@ fn generate_opaque_type(
             vis: respan(self.lower_span(span.shrink_to_lo()), hir::VisibilityKind::Inherited),
             span: self.lower_span(opaque_ty_span),
         };
-
-        // Insert the item into the global item list. This usually happens
-        // automatically for all AST items. But this opaque type item
-        // does not actually exist in the AST.
-        self.insert_item(opaque_ty_item);
+        hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
     }
 
     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
@@ -1594,7 +1509,7 @@ fn lower_fn_decl(
                 if let Some((_, ibty)) = &mut in_band_ty_params {
                     this.lower_ty_direct(
                         &param.ty,
-                        ImplTraitContext::Universal(ibty, this.current_hir_id_owner.0),
+                        ImplTraitContext::Universal(ibty, this.current_hir_id_owner),
                     )
                 } else {
                     this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
@@ -1685,7 +1600,7 @@ fn lower_async_fn_ret_ty(
 
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
 
-        let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id);
+        let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
 
         // When we create the opaque type for this async fn, it is going to have
         // to capture all the lifetimes involved in the signature (including in the
@@ -1735,7 +1650,8 @@ fn lower_async_fn_ret_ty(
         // grow.
         let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
 
-        let lifetime_params = self.with_hir_id_owner(opaque_ty_node_id, |this| {
+        let mut lifetime_params = Vec::new();
+        self.with_hir_id_owner(opaque_ty_node_id, |this| {
             // We have to be careful to get elision right here. The
             // idea is that we create a lifetime parameter for each
             // lifetime in the return type.  So, given a return type
@@ -1757,7 +1673,7 @@ fn lower_async_fn_ret_ty(
             //
             // Note: this must be done after lowering the output type,
             // as the output type may introduce new in-band lifetimes.
-            let lifetime_params: Vec<(Span, ParamName)> = this
+            lifetime_params = this
                 .in_scope_lifetimes
                 .iter()
                 .cloned()
@@ -1786,9 +1702,7 @@ fn lower_async_fn_ret_ty(
             };
 
             trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
-            this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
-
-            lifetime_params
+            this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
         });
 
         // As documented above on the variable
index 90a22b5c209522864143e6b40c2d20f2fa12af5e..929f427484dba4ac28ba65fd7bf931c067c46376 100644 (file)
@@ -99,7 +99,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         num_lifetimes,
                         parenthesized_generic_args,
                         itctx.reborrow(),
-                        None,
                     )
                 },
             )),
@@ -147,7 +146,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 0,
                 ParenthesizedGenericArgs::Err,
                 itctx.reborrow(),
-                None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);
 
@@ -178,7 +176,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         res: Res,
         p: &Path,
         param_mode: ParamMode,
-        explicit_owner: Option<NodeId>,
     ) -> &'hir hir::Path<'hir> {
         self.arena.alloc(hir::Path {
             res,
@@ -190,7 +187,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     0,
                     ParenthesizedGenericArgs::Err,
                     ImplTraitContext::disallowed(),
-                    explicit_owner,
                 )
             })),
             span: self.lower_span(p.span),
@@ -205,7 +201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> &'hir hir::Path<'hir> {
         let res = self.expect_full_res(id);
         let res = self.lower_res(res);
-        self.lower_path_extra(res, p, param_mode, None)
+        self.lower_path_extra(res, p, param_mode)
     }
 
     crate fn lower_path_segment(
@@ -216,7 +212,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         expected_lifetimes: usize,
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: ImplTraitContext<'_, 'hir>,
-        explicit_owner: Option<NodeId>,
     ) -> hir::PathSegment<'hir> {
         debug!(
             "path_span: {:?}, lower_path_segment(segment: {:?}, expected_lifetimes: {:?})",
@@ -354,11 +349,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         let res = self.expect_full_res(segment.id);
-        let id = if let Some(owner) = explicit_owner {
-            self.lower_node_id_with_owner(segment.id, owner)
-        } else {
-            self.lower_node_id(segment.id)
-        };
+        let id = self.lower_node_id(segment.id);
         debug!(
             "lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
             segment.ident, segment.id, id,
index 4a6eb80fb30ce1ed0bfc0ef92595d9520ba63876..9312a68bc600c15d75ff721b3088d4c4e56c006a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_ast_passes"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 itertools = "0.9"
index fa88740103ba3ed40f59f96d6fdb29ff87e20eab..29f2be4cf46486d4b46497edf6d0b715bad01d71 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_ast_pretty"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 0566379e1f5e1c39d05eab6702efd9199654dc64..ba310a6860e82386214c9205ac2f21aed3d52d89 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_attr"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index c683c388ba9ead0b7c939caade7db8e941eb5bb9..75e9c69af4e5c9d8bfab4a5963c327ee46ab03e0 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_borrowck"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 016fe0bb6dedffbe9ff419991993903f2c5cbde4..efd34f4e0a58e38b6098f47333c0a22165ce2599 100644 (file)
@@ -316,7 +316,8 @@ fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
             Rvalue::Use(ref operand)
             | Rvalue::Repeat(ref operand, _)
             | Rvalue::UnaryOp(_ /*un_op*/, ref operand)
-            | Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
+            | Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
+            | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
                 self.consume_operand(location, operand)
             }
 
index b3b7d7e02ccef068b444607116f3058a20ba0f10..72f4907a09f9849e4cf86f3ab54afd8b901629f7 100644 (file)
@@ -1361,7 +1361,8 @@ fn consume_rvalue(
             Rvalue::Use(ref operand)
             | Rvalue::Repeat(ref operand, _)
             | Rvalue::UnaryOp(_ /*un_op*/, ref operand)
-            | Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
+            | Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
+            | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
                 self.consume_operand(location, (operand, span), flow_state)
             }
 
index d790e31105c8aa2f2ee20c82662dce9c1a473959..b35e76b96ad9194423b0a145e6d3bd8604d96df7 100644 (file)
@@ -1,5 +1,9 @@
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::vec_map::VecMap;
+use rustc_hir::OpaqueTyOrigin;
+use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
@@ -50,13 +54,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     pub(crate) fn infer_opaque_types(
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
-        opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
+        opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
         span: Span,
     ) -> VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>> {
         opaque_ty_decls
             .into_iter()
-            .map(|(opaque_type_key, concrete_type)| {
+            .filter_map(|(opaque_type_key, decl)| {
                 let substs = opaque_type_key.substs;
+                let concrete_type = decl.concrete_ty;
                 debug!(?concrete_type, ?substs);
 
                 let mut subst_regions = vec![self.universal_regions.fr_static];
@@ -94,7 +99,13 @@ pub(crate) fn infer_opaque_types(
                     universal_concrete_type,
                     span,
                 );
-                (opaque_type_key, remapped_type)
+
+                check_opaque_type_parameter_valid(
+                    infcx.tcx,
+                    opaque_type_key,
+                    OpaqueTypeDecl { concrete_ty: remapped_type, ..decl },
+                )
+                .then_some((opaque_type_key, remapped_type))
             })
             .collect()
     }
@@ -119,3 +130,95 @@ pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
         })
     }
 }
+
+fn check_opaque_type_parameter_valid(
+    tcx: TyCtxt<'_>,
+    opaque_type_key: OpaqueTypeKey<'_>,
+    decl: OpaqueTypeDecl<'_>,
+) -> bool {
+    match decl.origin {
+        // No need to check return position impl trait (RPIT)
+        // because for type and const parameters they are correct
+        // by construction: we convert
+        //
+        // fn foo<P0..Pn>() -> impl Trait
+        //
+        // into
+        //
+        // type Foo<P0...Pn>
+        // fn foo<P0..Pn>() -> Foo<P0...Pn>.
+        //
+        // For lifetime parameters we convert
+        //
+        // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
+        //
+        // into
+        //
+        // type foo::<'p0..'pn>::Foo<'q0..'qm>
+        // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
+        //
+        // which would error here on all of the `'static` args.
+        OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
+        // Check these
+        OpaqueTyOrigin::TyAlias => {}
+    }
+    let span = decl.definition_span;
+    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+    let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
+    for (i, arg) in opaque_type_key.substs.iter().enumerate() {
+        let arg_is_param = match arg.unpack() {
+            GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
+            GenericArgKind::Lifetime(ty::ReStatic) => {
+                tcx.sess
+                    .struct_span_err(span, "non-defining opaque type use in defining scope")
+                    .span_label(
+                        tcx.def_span(opaque_generics.param_at(i, tcx).def_id),
+                        "cannot use static lifetime; use a bound lifetime \
+                                    instead or remove the lifetime parameter from the \
+                                    opaque type",
+                    )
+                    .emit();
+                return false;
+            }
+            GenericArgKind::Lifetime(lt) => {
+                matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
+            }
+            GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
+        };
+
+        if arg_is_param {
+            seen_params.entry(arg).or_default().push(i);
+        } else {
+            // Prevent `fn foo() -> Foo<u32>` from being defining.
+            let opaque_param = opaque_generics.param_at(i, tcx);
+            tcx.sess
+                .struct_span_err(span, "non-defining opaque type use in defining scope")
+                .span_note(
+                    tcx.def_span(opaque_param.def_id),
+                    &format!(
+                        "used non-generic {} `{}` for generic parameter",
+                        opaque_param.kind.descr(),
+                        arg,
+                    ),
+                )
+                .emit();
+            return false;
+        }
+    }
+
+    for (_, indices) in seen_params {
+        if indices.len() > 1 {
+            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
+            let spans: Vec<_> = indices
+                .into_iter()
+                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
+                .collect();
+            tcx.sess
+                .struct_span_err(span, "non-defining opaque type use in defining scope")
+                .span_note(spans, &format!("{} used multiple times", descr))
+                .emit();
+            return false;
+        }
+    }
+    true
+}
index 18070164e82195f7430c297fe9926b07f86f5f15..e77619882228139f12a99e700b8d289e4856837c 100644 (file)
@@ -89,10 +89,10 @@ pub(super) fn prove_trait_ref(
         category: ConstraintCategory,
     ) {
         self.prove_predicates(
-            Some(ty::PredicateKind::Trait(ty::TraitPredicate {
+            Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
                 trait_ref,
                 constness: ty::BoundConstness::NotConst,
-            })),
+            }))),
             locations,
             category,
         );
index 5ccf380602554bfed8eb5c3b2b75b24f489861a8..cf50fa38687b55a7ef58f6559dce62dba3154d90 100644 (file)
@@ -14,6 +14,7 @@
 use rustc_hir::lang_items::LangItem;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::canonical::QueryRegionConstraints;
+use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{
@@ -193,16 +194,17 @@ pub(crate) fn type_check<'mir, 'tcx>(
 
             opaque_type_values
                 .into_iter()
-                .filter_map(|(opaque_type_key, decl)| {
-                    let mut revealed_ty = infcx.resolve_vars_if_possible(decl.concrete_ty);
-                    if revealed_ty.has_infer_types_or_consts() {
+                .filter_map(|(opaque_type_key, mut decl)| {
+                    decl.concrete_ty = infcx.resolve_vars_if_possible(decl.concrete_ty);
+                    if decl.concrete_ty.has_infer_types_or_consts() {
                         infcx.tcx.sess.delay_span_bug(
                             body.span,
-                            &format!("could not resolve {:#?}", revealed_ty.kind()),
+                            &format!("could not resolve {:#?}", decl.concrete_ty.kind()),
                         );
-                        revealed_ty = infcx.tcx.ty_error();
+                        decl.concrete_ty = infcx.tcx.ty_error();
                     }
-                    let concrete_is_opaque = if let ty::Opaque(def_id, _) = revealed_ty.kind() {
+                    let concrete_is_opaque = if let ty::Opaque(def_id, _) = decl.concrete_ty.kind()
+                    {
                         *def_id == opaque_type_key.def_id
                     } else {
                         false
@@ -234,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
                         );
                         None
                     } else {
-                        Some((opaque_type_key, revealed_ty))
+                        Some((opaque_type_key, decl))
                     }
                 })
                 .collect()
@@ -890,7 +892,7 @@ struct BorrowCheckContext<'a, 'tcx> {
 crate struct MirTypeckResults<'tcx> {
     crate constraints: MirTypeckRegionConstraints<'tcx>,
     crate universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
+    crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
 }
 
 /// A collection of region constraints that must be satisfied for the
@@ -1078,7 +1080,8 @@ fn check_user_type_annotations(&mut self) {
                     }
 
                     self.prove_predicate(
-                        ty::PredicateKind::WellFormed(inferred_ty.into()).to_predicate(self.tcx()),
+                        ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into()))
+                            .to_predicate(self.tcx()),
                         Locations::All(span),
                         ConstraintCategory::TypeAnnotation,
                     );
@@ -1314,7 +1317,8 @@ fn eq_opaque_type_and_type(
                     obligations.obligations.push(traits::Obligation::new(
                         ObligationCause::dummy(),
                         param_env,
-                        ty::PredicateKind::WellFormed(revealed_ty.into()).to_predicate(infcx.tcx),
+                        ty::Binder::dummy(ty::PredicateKind::WellFormed(revealed_ty.into()))
+                            .to_predicate(infcx.tcx),
                     ));
                     obligations.add(
                         infcx
@@ -1597,7 +1601,9 @@ fn check_terminator(
                 self.check_call_dest(body, term, &sig, destination, term_location);
 
                 self.prove_predicates(
-                    sig.inputs_and_output.iter().map(|ty| ty::PredicateKind::WellFormed(ty.into())),
+                    sig.inputs_and_output
+                        .iter()
+                        .map(|ty| ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))),
                     term_location.to_locations(),
                     ConstraintCategory::Boring,
                 );
@@ -2018,13 +2024,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
                 }
             }
 
-            Rvalue::NullaryOp(_, ty) => {
-                // Even with unsized locals cannot box an unsized value.
-                if self.unsized_feature_enabled() {
-                    let span = body.source_info(location).span;
-                    self.ensure_place_sized(ty, span);
-                }
-
+            Rvalue::NullaryOp(_, ty) | Rvalue::ShallowInitBox(_, ty) => {
                 let trait_ref = ty::TraitRef {
                     def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
                     substs: tcx.mk_substs_trait(ty, &[]),
@@ -2357,6 +2357,7 @@ fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationInde
             | Rvalue::AddressOf(..)
             | Rvalue::Len(..)
             | Rvalue::Cast(..)
+            | Rvalue::ShallowInitBox(..)
             | Rvalue::BinaryOp(..)
             | Rvalue::CheckedBinaryOp(..)
             | Rvalue::NullaryOp(..)
index 2370ac201b0182b7211f4c8e5de65dc5bcae124d..fd34f947f72c0eec04edab81c958efab63234d19 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_builtin_macros"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index d7b46f282151fe32ac11e8dc1432d98f0ba58bb6..307730f7f5f14a9f88f4f627fe2a3b03f84fc3e8 100644 (file)
@@ -2,6 +2,7 @@
 
 use rustc_ast as ast;
 use rustc_ast::mut_visit::MutVisitor;
+use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::CanSynthesizeMissingTokens;
 use rustc_ast::visit::Visitor;
 use rustc_ast::{mut_visit, visit};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_expand::config::StripUnconfigured;
 use rustc_expand::configure;
+use rustc_feature::Features;
 use rustc_parse::parser::ForceCollect;
 use rustc_session::utils::FlattenNonterminals;
-
-use rustc_ast::ptr::P;
+use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use smallvec::SmallVec;
     annotatable: Annotatable,
 ) -> Vec<Annotatable> {
     check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
-    vec![cfg_eval(ecx, annotatable)]
+    vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable)]
 }
 
-crate fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Annotatable {
-    CfgEval {
-        cfg: &mut StripUnconfigured {
-            sess: ecx.sess,
-            features: ecx.ecfg.features,
-            config_tokens: true,
-        },
-    }
-    .configure_annotatable(annotatable)
-    // Since the item itself has already been configured by the `InvocationCollector`,
-    // we know that fold result vector will contain exactly one element.
-    .unwrap()
+crate fn cfg_eval(
+    sess: &Session,
+    features: Option<&Features>,
+    annotatable: Annotatable,
+) -> Annotatable {
+    CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true } }
+        .configure_annotatable(annotatable)
+        // Since the item itself has already been configured by the `InvocationCollector`,
+        // we know that fold result vector will contain exactly one element.
+        .unwrap()
 }
 
 struct CfgEval<'a, 'b> {
index e0389f448ebf29abf7a48d5bc6bedbfba329fdb7..241c90c157125e5c90daae48737a863c763dead1 100644 (file)
@@ -1,12 +1,13 @@
 use crate::cfg_eval::cfg_eval;
 
-use rustc_ast::{self as ast, attr, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
+use rustc_ast as ast;
+use rustc_ast::{attr, token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
 use rustc_feature::AttributeTemplate;
 use rustc_parse::validate_attr;
 use rustc_session::Session;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
 crate struct Expander;
@@ -26,8 +27,7 @@ fn expand(
             return ExpandResult::Ready(vec![item]);
         }
 
-        let item = cfg_eval(ecx, item);
-
+        let (sess, features) = (ecx.sess, ecx.ecfg.features);
         let result =
             ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
                 let template =
@@ -40,7 +40,8 @@ fn expand(
                     template,
                 );
 
-                attr.meta_item_list()
+                let mut resolutions: Vec<_> = attr
+                    .meta_item_list()
                     .unwrap_or_default()
                     .into_iter()
                     .filter_map(|nested_meta| match nested_meta {
@@ -56,8 +57,21 @@ fn expand(
                         report_path_args(sess, &meta);
                         meta.path
                     })
-                    .map(|path| (path, item.clone(), None))
-                    .collect()
+                    .map(|path| (path, dummy_annotatable(), None))
+                    .collect();
+
+                // Do not configure or clone items unless necessary.
+                match &mut resolutions[..] {
+                    [] => {}
+                    [(_, first_item, _), others @ ..] => {
+                        *first_item = cfg_eval(sess, features, item.clone());
+                        for (_, item, _) in others {
+                            *item = first_item.clone();
+                        }
+                    }
+                }
+
+                resolutions
             });
 
         match result {
@@ -67,6 +81,18 @@ fn expand(
     }
 }
 
+// The cheapest `Annotatable` to construct.
+fn dummy_annotatable() -> Annotatable {
+    Annotatable::GenericParam(ast::GenericParam {
+        id: ast::DUMMY_NODE_ID,
+        ident: Ident::invalid(),
+        attrs: Default::default(),
+        bounds: Default::default(),
+        is_placeholder: false,
+        kind: GenericParamKind::Lifetime,
+    })
+}
+
 fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
     let item_kind = match item {
         Annotatable::Item(item) => Some(&item.kind),
index c7626dec4d7c0b29bc5c07efb1f0f2c1a0154906..1c9c6834c100c5c8c3db35461c19a9d0cec4c38e 100644 (file)
@@ -164,23 +164,22 @@ fn parse_args<'a>(
                 p.clear_expected_tokens();
             }
 
-            // `Parser::expect` tries to recover using the
-            // `Parser::unexpected_try_recover` function. This function is able
-            // to recover if the expected token is a closing delimiter.
-            //
-            // As `,` is not a closing delimiter, it will always return an `Err`
-            // variant.
-            let mut err = p.expect(&token::Comma).unwrap_err();
-
-            match token::TokenKind::Comma.similar_tokens() {
-                Some(tks) if tks.contains(&p.token.kind) => {
-                    // If a similar token is found, then it may be a typo. We
-                    // consider it as a comma, and continue parsing.
-                    err.emit();
-                    p.bump();
+            match p.expect(&token::Comma) {
+                Err(mut err) => {
+                    match token::TokenKind::Comma.similar_tokens() {
+                        Some(tks) if tks.contains(&p.token.kind) => {
+                            // If a similar token is found, then it may be a typo. We
+                            // consider it as a comma, and continue parsing.
+                            err.emit();
+                            p.bump();
+                        }
+                        // Otherwise stop the parsing and return the error.
+                        _ => return Err(err),
+                    }
+                }
+                Ok(recovered) => {
+                    assert!(recovered);
                 }
-                // Otherwise stop the parsing and return the error.
-                _ => return Err(err),
             }
         }
         first = false;
@@ -845,8 +844,7 @@ fn into_expr(self) -> P<ast::Expr> {
             self.ecx.expr_match(self.macsp, head, vec![arm])
         };
 
-        let ident = Ident::from_str_and_span("args", self.macsp);
-        let args_slice = self.ecx.expr_ident(self.macsp, ident);
+        let args_slice = self.ecx.expr_addr_of(self.macsp, args_match);
 
         // Now create the fmt::Arguments struct with all our locals we created.
         let (fn_name, fn_args) = if self.all_pieces_simple {
@@ -856,25 +854,22 @@ fn into_expr(self) -> P<ast::Expr> {
             // nonstandard placeholders, if there are any.
             let fmt = self.ecx.expr_vec_slice(self.macsp, self.pieces);
 
-            ("new_v1_formatted", vec![pieces, args_slice, fmt])
+            let path = self.ecx.std_path(&[sym::fmt, sym::UnsafeArg, sym::new]);
+            let unsafe_arg = self.ecx.expr_call_global(self.macsp, path, Vec::new());
+            let unsafe_expr = self.ecx.expr_block(P(ast::Block {
+                stmts: vec![self.ecx.stmt_expr(unsafe_arg)],
+                id: ast::DUMMY_NODE_ID,
+                rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated),
+                span: self.macsp,
+                tokens: None,
+                could_be_bare_literal: false,
+            }));
+
+            ("new_v1_formatted", vec![pieces, args_slice, fmt, unsafe_expr])
         };
 
         let path = self.ecx.std_path(&[sym::fmt, sym::Arguments, Symbol::intern(fn_name)]);
-        let arguments = self.ecx.expr_call_global(self.macsp, path, fn_args);
-        let body = self.ecx.expr_block(P(ast::Block {
-            stmts: vec![self.ecx.stmt_expr(arguments)],
-            id: ast::DUMMY_NODE_ID,
-            rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated),
-            span: self.macsp,
-            tokens: None,
-            could_be_bare_literal: false,
-        }));
-
-        let ident = Ident::from_str_and_span("args", self.macsp);
-        let binding_mode = ast::BindingMode::ByRef(ast::Mutability::Not);
-        let pat = self.ecx.pat_ident_binding_mode(self.macsp, ident, binding_mode);
-        let arm = self.ecx.arm(self.macsp, pat, body);
-        self.ecx.expr_match(self.macsp, args_match, vec![arm])
+        self.ecx.expr_call_global(self.macsp, path, fn_args)
     }
 
     fn format_arg(
index 6f40fc0fcb881e77fa67e548191d380321f70550..61d40702a32842d2769040023e6a59f0c1c2fcc3 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_codegen_cranelift"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 crate-type = ["dylib"]
index d8fa2c769046827fa36c332f1e5d71047ef68507..1b30edd293862b1d221cbfb4529c1b9f8883a52e 100644 (file)
@@ -701,6 +701,13 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
                     let len = codegen_array_len(fx, place);
                     lval.write_cvalue(fx, CValue::by_val(len, usize_layout));
                 }
+                Rvalue::ShallowInitBox(ref operand, content_ty) => {
+                    let content_ty = fx.monomorphize(content_ty);
+                    let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
+                    let operand = codegen_operand(fx, operand);
+                    let operand = operand.load_scalar(fx);
+                    lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
+                }
                 Rvalue::NullaryOp(NullOp::Box, content_ty) => {
                     let usize_type = fx.clif_type(fx.tcx.types.usize).unwrap();
                     let content_ty = fx.monomorphize(content_ty);
index e7cd5edbbf654a2888e6b0ba4965da554f37f4a1..89e0cb8d90ecd6c58bef18c764a66f9cc59b8654 100644 (file)
@@ -8,7 +8,6 @@
 
 #![feature(rustc_private)]
 
-extern crate rustc_data_structures;
 extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate rustc_session;
index 3c99febbd57cc952faafcf62a69101e9dbb8d231..3f02443458188caf558798b62cafee72ef154454 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_codegen_llvm"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 test = false
index 56b93f83466805d32302878c4fbfa5923ae71f4f..51c70f0868f2697571943a4366d01e38506f9e9f 100644 (file)
@@ -305,9 +305,12 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
     let mut function_features = codegen_fn_attrs
         .target_features
         .iter()
-        .map(|f| {
+        .flat_map(|f| {
             let feature = &f.as_str();
-            format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
+            llvm_util::to_llvm_feature(cx.tcx.sess, feature)
+                .into_iter()
+                .map(|f| format!("+{}", f))
+                .collect::<Vec<String>>()
         })
         .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
             InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
index f612785e5a416c582321e4efa0b7c1aec41e91b6..99b30264d09580bc858644f00670d3250d83b659 100644 (file)
@@ -325,6 +325,20 @@ fn fat_lto(
         drop(linker);
         save_temp_bitcode(&cgcx, &module, "lto.input");
 
+        // Fat LTO also suffers from the invalid DWARF issue similar to Thin LTO.
+        // Here we rewrite all `DICompileUnit` pointers if there is only one `DICompileUnit`.
+        // This only works around the problem when codegen-units = 1.
+        // Refer to the comments in the `optimize_thin_module` function for more details.
+        let mut cu1 = ptr::null_mut();
+        let mut cu2 = ptr::null_mut();
+        unsafe { llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2) };
+        if !cu2.is_null() {
+            let _timer =
+                cgcx.prof.generic_activity_with_arg("LLVM_fat_lto_patch_debuginfo", &*module.name);
+            unsafe { llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1) };
+            save_temp_bitcode(cgcx, &module, "fat-lto-after-patch");
+        }
+
         // Internalize everything below threshold to help strip out more modules and such.
         unsafe {
             let ptr = symbols_below_threshold.as_ptr();
@@ -748,7 +762,7 @@ pub unsafe fn optimize_thin_module(
         // an error.
         let mut cu1 = ptr::null_mut();
         let mut cu2 = ptr::null_mut();
-        llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
+        llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
         if !cu2.is_null() {
             let msg = "multiple source DICompileUnits found";
             return Err(write::llvm_err(&diag_handler, msg));
@@ -847,7 +861,7 @@ pub unsafe fn optimize_thin_module(
             let _timer = cgcx
                 .prof
                 .generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
-            llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
+            llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1);
             save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
         }
 
index 791604a18273d62ef6567329572419f50c93c310..92199f611bad03baa517c0425a28e1aa98a4bb36 100644 (file)
@@ -370,8 +370,9 @@ fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
 }
 
 pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
-    // The new pass manager is disabled by default.
-    config.new_llvm_pass_manager.unwrap_or(false)
+    // The new pass manager is enabled by default for LLVM >= 13.
+    // This matches Clang, which also enables it since Clang 13.
+    config.new_llvm_pass_manager.unwrap_or_else(|| llvm_util::get_version() >= (13, 0, 0))
 }
 
 pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
index 37b3279fb80966dd3058b49c412e31fe70e9b087..be55a0c868a462c38a37a429c12fe178911d59ff 100644 (file)
@@ -96,7 +96,6 @@ fn codegen_intrinsic_call(
         let arg_tys = sig.inputs();
         let ret_ty = sig.output();
         let name = tcx.item_name(def_id);
-        let name_str = &*name.as_str();
 
         let llret_ty = self.layout_of(ret_ty).llvm_type(self);
         let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
@@ -230,9 +229,14 @@ fn codegen_intrinsic_call(
                                 &[args[0].immediate(), y],
                             )
                         }
-                        sym::ctlz_nonzero | sym::cttz_nonzero => {
+                        sym::ctlz_nonzero => {
                             let y = self.const_bool(true);
-                            let llvm_name = &format!("llvm.{}.i{}", &name_str[..4], width);
+                            let llvm_name = &format!("llvm.ctlz.i{}", width);
+                            self.call_intrinsic(llvm_name, &[args[0].immediate(), y])
+                        }
+                        sym::cttz_nonzero => {
+                            let y = self.const_bool(true);
+                            let llvm_name = &format!("llvm.cttz.i{}", width);
                             self.call_intrinsic(llvm_name, &[args[0].immediate(), y])
                         }
                         sym::ctpop => self.call_intrinsic(
@@ -353,7 +357,7 @@ fn codegen_intrinsic_call(
                 return;
             }
 
-            _ if name_str.starts_with("simd_") => {
+            _ if name.as_str().starts_with("simd_") => {
                 match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
                     Ok(llval) => llval,
                     Err(()) => return,
@@ -843,7 +847,6 @@ macro_rules! require_simd {
     let sig =
         tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
     let arg_tys = sig.inputs();
-    let name_str = &*name.as_str();
 
     if name == sym::simd_select_bitmask {
         let in_ty = arg_tys[0];
@@ -917,7 +920,7 @@ macro_rules! require_simd {
         ));
     }
 
-    if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
+    if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") {
         // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
         // If there is no suffix, use the index array length.
         let n: u64 = if stripped.is_empty() {
index 3f2ed02d90df3d78889facb1131e0f86b76236e0..d8c2a345fb03cc5771214aa5806be877c8aa5ab9 100644 (file)
@@ -2377,12 +2377,8 @@ pub fn LLVMRustGetBitcodeSliceFromObjectData(
         len: usize,
         out_len: &mut usize,
     ) -> *const u8;
-    pub fn LLVMRustThinLTOGetDICompileUnit(
-        M: &Module,
-        CU1: &mut *mut c_void,
-        CU2: &mut *mut c_void,
-    );
-    pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
+    pub fn LLVMRustLTOGetDICompileUnit(M: &Module, CU1: &mut *mut c_void, CU2: &mut *mut c_void);
+    pub fn LLVMRustLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
 
     pub fn LLVMRustLinkerNew(M: &'a Module) -> &'a mut Linker<'a>;
     pub fn LLVMRustLinkerAdd(
index 3b64ec1a99122c389952e810f7c6a3f0bdf9f219..f9172e437733f816a1084e9c7b68dbed136793f0 100644 (file)
@@ -166,25 +166,32 @@ pub fn time_trace_profiler_finish(file_name: &str) {
 // Though note that Rust can also be build with an external precompiled version of LLVM
 // which might lead to failures if the oldest tested / supported LLVM version
 // doesn't yet support the relevant intrinsics
-pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
+pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> Vec<&'a str> {
     let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
     match (arch, s) {
-        ("x86", "pclmulqdq") => "pclmul",
-        ("x86", "rdrand") => "rdrnd",
-        ("x86", "bmi1") => "bmi",
-        ("x86", "cmpxchg16b") => "cx16",
-        ("x86", "avx512vaes") => "vaes",
-        ("x86", "avx512gfni") => "gfni",
-        ("x86", "avx512vpclmulqdq") => "vpclmulqdq",
-        ("aarch64", "fp") => "fp-armv8",
-        ("aarch64", "fp16") => "fullfp16",
-        ("aarch64", "fhm") => "fp16fml",
-        ("aarch64", "rcpc2") => "rcpc-immo",
-        ("aarch64", "dpb") => "ccpp",
-        ("aarch64", "dpb2") => "ccdp",
-        ("aarch64", "frintts") => "fptoint",
-        ("aarch64", "fcma") => "complxnum",
-        (_, s) => s,
+        ("x86", "sse4.2") => {
+            if get_version() >= (14, 0, 0) {
+                vec!["sse4.2", "crc32"]
+            } else {
+                vec!["sse4.2"]
+            }
+        }
+        ("x86", "pclmulqdq") => vec!["pclmul"],
+        ("x86", "rdrand") => vec!["rdrnd"],
+        ("x86", "bmi1") => vec!["bmi"],
+        ("x86", "cmpxchg16b") => vec!["cx16"],
+        ("x86", "avx512vaes") => vec!["vaes"],
+        ("x86", "avx512gfni") => vec!["gfni"],
+        ("x86", "avx512vpclmulqdq") => vec!["vpclmulqdq"],
+        ("aarch64", "fp") => vec!["fp-armv8"],
+        ("aarch64", "fp16") => vec!["fullfp16"],
+        ("aarch64", "fhm") => vec!["fp16fml"],
+        ("aarch64", "rcpc2") => vec!["rcpc-immo"],
+        ("aarch64", "dpb") => vec!["ccpp"],
+        ("aarch64", "dpb2") => vec!["ccdp"],
+        ("aarch64", "frintts") => vec!["fptoint"],
+        ("aarch64", "fcma") => vec!["complxnum"],
+        (_, s) => vec![s],
     }
 }
 
@@ -198,9 +205,13 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
             },
         )
         .filter(|feature| {
-            let llvm_feature = to_llvm_feature(sess, feature);
-            let cstr = CString::new(llvm_feature).unwrap();
-            unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) }
+            for llvm_feature in to_llvm_feature(sess, feature) {
+                let cstr = CString::new(llvm_feature).unwrap();
+                if unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
+                    return true;
+                }
+            }
+            false
         })
         .map(|feature| Symbol::intern(feature))
         .collect()
@@ -253,12 +264,19 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
     let mut rustc_target_features = supported_target_features(sess)
         .iter()
         .filter_map(|(feature, _gate)| {
-            let llvm_feature = to_llvm_feature(sess, *feature);
-            // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
-            target_features.binary_search_by_key(&llvm_feature, |(f, _d)| *f).ok().map(|index| {
-                let (_f, desc) = target_features.remove(index);
-                (*feature, desc)
-            })
+            for llvm_feature in to_llvm_feature(sess, *feature) {
+                // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
+                match target_features.binary_search_by_key(&llvm_feature, |(f, _d)| (*f)).ok().map(
+                    |index| {
+                        let (_f, desc) = target_features.remove(index);
+                        (*feature, desc)
+                    },
+                ) {
+                    Some(v) => return Some(v),
+                    None => {}
+                }
+            }
+            None
         })
         .collect::<Vec<_>>();
     rustc_target_features.extend_from_slice(&[(
@@ -373,30 +391,30 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
 
     let filter = |s: &str| {
         if s.is_empty() {
-            return None;
+            return vec![];
         }
         let feature = if s.starts_with('+') || s.starts_with('-') {
             &s[1..]
         } else {
-            return Some(s.to_string());
+            return vec![s.to_string()];
         };
         // Rustc-specific feature requests like `+crt-static` or `-crt-static`
         // are not passed down to LLVM.
         if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
-            return None;
+            return vec![];
         }
         // ... otherwise though we run through `to_llvm_feature` feature when
         // passing requests down to LLVM. This means that all in-language
         // features also work on the command line instead of having two
         // different names when the LLVM name and the Rust name differ.
-        Some(format!("{}{}", &s[..1], to_llvm_feature(sess, feature)))
+        to_llvm_feature(sess, feature).iter().map(|f| format!("{}{}", &s[..1], f)).collect()
     };
 
     // Features implied by an implicit or explicit `--target`.
-    features.extend(sess.target.features.split(',').filter_map(&filter));
+    features.extend(sess.target.features.split(',').flat_map(&filter));
 
     // -Ctarget-features
-    features.extend(sess.opts.cg.target_feature.split(',').filter_map(&filter));
+    features.extend(sess.opts.cg.target_feature.split(',').flat_map(&filter));
 
     features
 }
index 757ccbddbeedf140c425a1eaee7608f048fcbd77..9e03fc33ae0f18fbf606920ea6c7585209519236 100644 (file)
@@ -4,7 +4,7 @@
 use rustc_codegen_ssa::traits::*;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
-use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
 use rustc_target::abi::{Int, Pointer, F32, F64};
@@ -43,7 +43,8 @@ fn uncached_llvm_type<'a, 'tcx>(
         // in problematically distinct types due to HRTB and subtyping (see #47638).
         // ty::Dynamic(..) |
         ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str => {
-            let mut name = with_no_trimmed_paths(|| layout.ty.to_string());
+            let mut name =
+                with_no_visible_paths(|| with_no_trimmed_paths(|| layout.ty.to_string()));
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
             {
index 1446624b8815743269f2124ff20e6ce4ebf8b125..0713e167c53b8b73a7962f0bd2100e13c60444c3 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_codegen_ssa"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 test = false
index 4be050fb88c2da7c936792c2ff280c951cba0329..b0a5631549df85af3bd872d04f00fd6bac9a84b7 100644 (file)
@@ -15,7 +15,7 @@
 use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::{self, SwitchTargets};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
-use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
 use rustc_span::source_map::Span;
 use rustc_span::{sym, Symbol};
@@ -476,15 +476,20 @@ enum AssertIntrinsic {
                 UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false),
             };
             if do_panic {
-                let msg_str = with_no_trimmed_paths(|| {
-                    if layout.abi.is_uninhabited() {
-                        // Use this error even for the other intrinsics as it is more precise.
-                        format!("attempted to instantiate uninhabited type `{}`", ty)
-                    } else if intrinsic == ZeroValid {
-                        format!("attempted to zero-initialize type `{}`, which is invalid", ty)
-                    } else {
-                        format!("attempted to leave type `{}` uninitialized, which is invalid", ty)
-                    }
+                let msg_str = with_no_visible_paths(|| {
+                    with_no_trimmed_paths(|| {
+                        if layout.abi.is_uninhabited() {
+                            // Use this error even for the other intrinsics as it is more precise.
+                            format!("attempted to instantiate uninhabited type `{}`", ty)
+                        } else if intrinsic == ZeroValid {
+                            format!("attempted to zero-initialize type `{}`, which is invalid", ty)
+                        } else {
+                            format!(
+                                "attempted to leave type `{}` uninitialized, which is invalid",
+                                ty
+                            )
+                        }
+                    })
                 });
                 let msg = bx.const_str(Symbol::intern(&msg_str));
                 let location = self.get_caller_location(bx, source_info).immediate();
@@ -777,22 +782,30 @@ fn codegen_call_terminator(
 
             self.codegen_argument(&mut bx, op, &mut llargs, &fn_abi.args[i]);
         }
-        if let Some(tup) = untuple {
+        let num_untupled = untuple.map(|tup| {
             self.codegen_arguments_untupled(
                 &mut bx,
                 tup,
                 &mut llargs,
                 &fn_abi.args[first_args.len()..],
             )
-        }
+        });
 
         let needs_location =
             instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx()));
         if needs_location {
+            let mir_args = if let Some(num_untupled) = num_untupled {
+                first_args.len() + num_untupled
+            } else {
+                args.len()
+            };
             assert_eq!(
                 fn_abi.args.len(),
-                args.len() + 1,
-                "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR",
+                mir_args + 1,
+                "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR: {:?} {:?} {:?}",
+                instance,
+                fn_span,
+                fn_abi,
             );
             let location =
                 self.get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info });
@@ -1122,7 +1135,7 @@ fn codegen_arguments_untupled(
         operand: &mir::Operand<'tcx>,
         llargs: &mut Vec<Bx::Value>,
         args: &[ArgAbi<'tcx, Ty<'tcx>>],
-    ) {
+    ) -> usize {
         let tuple = self.codegen_operand(bx, operand);
 
         // Handle both by-ref and immediate tuples.
@@ -1142,6 +1155,7 @@ fn codegen_arguments_untupled(
                 self.codegen_argument(bx, op, llargs, &args[i]);
             }
         }
+        tuple.layout.fields.count()
     }
 
     fn get_caller_location(
index c139f915e6cbb21932924f897e7a2822da161658..c710fcc2c1dcb665e131a2bd147c2fbced879c61 100644 (file)
@@ -3,9 +3,11 @@
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{BytePos, Span};
+use rustc_target::abi::Abi;
 use rustc_target::abi::Size;
 
 use super::operand::{OperandRef, OperandValue};
@@ -368,21 +370,14 @@ pub fn compute_per_local_var_debug_info(
                         {
                             let arg_index = place.local.index() - 1;
                             if target_is_msvc {
-                                // Rust compiler decomposes every &str or slice argument into two components:
-                                // a pointer to the memory address where the data is stored and a usize representing
-                                // the length of the str (or slice). These components will later be used to reconstruct
-                                // the original argument inside the body of the function that owns it (see the
-                                // definition of debug_introduce_local for more details).
-                                //
-                                // Since the original argument is declared inside a function rather than being passed
-                                // in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize
-                                // its data correctly. (See issue #81894 for an in-depth description of the problem).
-                                match *var_ty.kind() {
-                                    ty::Ref(_, inner_type, _) => match *inner_type.kind() {
-                                        ty::Slice(_) | ty::Str => VariableKind::LocalVariable,
-                                        _ => VariableKind::ArgumentVariable(arg_index + 1),
-                                    },
-                                    _ => VariableKind::ArgumentVariable(arg_index + 1),
+                                // ScalarPair parameters are spilled to the stack so they need to
+                                // be marked as a `LocalVariable` for MSVC debuggers to visualize
+                                // their data correctly. (See #81894 & #88625)
+                                let var_ty_layout = self.cx.layout_of(var_ty);
+                                if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
+                                    VariableKind::LocalVariable
+                                } else {
+                                    VariableKind::ArgumentVariable(arg_index + 1)
                                 }
                             } else {
                                 // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
index 8e3982c72d7742408951922d31ad4da40b64755c..476ddbd93980ca76565fd2d9579fa0c3fc80bc5b 100644 (file)
@@ -129,6 +129,7 @@ fn new_operand<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
 
 ///////////////////////////////////////////////////////////////////////////
 
+#[instrument(level = "debug", skip(cx))]
 pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     instance: Instance<'tcx>,
@@ -257,6 +258,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     let mut idx = 0;
     let mut llarg_idx = fx.fn_abi.ret.is_indirect() as usize;
 
+    let mut num_untupled = None;
+
     let args = mir
         .args_iter()
         .enumerate()
@@ -285,6 +288,11 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                     let pr_field = place.project_field(bx, i);
                     bx.store_fn_arg(arg, &mut llarg_idx, pr_field);
                 }
+                assert_eq!(
+                    None,
+                    num_untupled.replace(tupled_arg_tys.len()),
+                    "Replaced existing num_tupled"
+                );
 
                 return LocalRef::Place(place);
             }
@@ -361,10 +369,17 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         .collect::<Vec<_>>();
 
     if fx.instance.def.requires_caller_location(bx.tcx()) {
+        let mir_args = if let Some(num_untupled) = num_untupled {
+            // Subtract off the tupled argument that gets 'expanded'
+            args.len() - 1 + num_untupled
+        } else {
+            args.len()
+        };
         assert_eq!(
             fx.fn_abi.args.len(),
-            args.len() + 1,
-            "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR",
+            mir_args + 1,
+            "#[track_caller] instance {:?} must have 1 more argument in their ABI than in their MIR",
+            fx.instance
         );
 
         let arg = fx.fn_abi.args.last().unwrap();
index 7403c21a9060e0e17da08a9b325d87525970cf99..f087b9f7815da73a1b3bb79661b149a34124f000 100644 (file)
@@ -550,6 +550,18 @@ pub fn codegen_rvalue_operand(
                     OperandRef::new_zst(&mut bx, self.cx.layout_of(self.monomorphize(ty)));
                 (bx, operand)
             }
+            mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
+                let operand = self.codegen_operand(&mut bx, operand);
+                let lloperand = operand.immediate();
+
+                let content_ty = self.monomorphize(content_ty);
+                let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty));
+                let llty_ptr = bx.cx().backend_type(box_layout);
+
+                let val = bx.pointercast(lloperand, llty_ptr);
+                let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
+                (bx, operand)
+            }
         }
     }
 
@@ -763,6 +775,7 @@ pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) ->
             mir::Rvalue::AddressOf(..) |
             mir::Rvalue::Len(..) |
             mir::Rvalue::Cast(..) | // (*)
+            mir::Rvalue::ShallowInitBox(..) | // (*)
             mir::Rvalue::BinaryOp(..) |
             mir::Rvalue::CheckedBinaryOp(..) |
             mir::Rvalue::UnaryOp(..) |
index 1653d5cf6c560ae42e05550cf2a72f1491ca366d..a51273732ae6f8b335c4dfb137770dfdfd6f1232 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_const_eval"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 6e35b33188cd238b858d1f3e696cebe86f49f364..bcce19b28db97444e189f25833a497dd45d9ae96 100644 (file)
@@ -289,6 +289,12 @@ pub fn eval_rvalue_into_place(
                 self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?;
             }
 
+            ShallowInitBox(ref operand, _) => {
+                let src = self.eval_operand(operand, None)?;
+                let v = self.read_immediate(&src)?;
+                self.write_immediate(*v, &dest)?;
+            }
+
             Cast(cast_kind, ref operand, cast_ty) => {
                 let src = self.eval_operand(operand, None)?;
                 let cast_ty = self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty);
index a6375ad0e02cf1e4011a163d6ac5279c7011affb..fc69770bf6a306f68bd89aa3f2ff60005507b4e2 100644 (file)
@@ -77,7 +77,7 @@ macro_rules! throw_validation_failure {
 ///
 macro_rules! try_validation {
     ($e:expr, $where:expr,
-    $( $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)?
+    $( $( $p:pat_param )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)?
     ) => {{
         match $e {
             Ok(x) => x,
index 9eec930f59e525cf5212e02cbadbf2226cd2bcb2..57d92005a56497ce3e63a19efcc73c5c9843d067 100644 (file)
@@ -650,6 +650,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
 
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
             Rvalue::NullaryOp(NullOp::Box, _) => self.check_op(ops::HeapAllocation),
+            Rvalue::ShallowInitBox(_, _) => {}
 
             Rvalue::UnaryOp(_, ref operand) => {
                 let ty = operand.ty(self.body, self.tcx);
@@ -912,6 +913,11 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                     return;
                 }
 
+                if Some(callee) == tcx.lang_items().exchange_malloc_fn() {
+                    self.check_op(ops::HeapAllocation);
+                    return;
+                }
+
                 // `async` blocks get lowered to `std::future::from_generator(/* a closure */)`.
                 let is_async_block = Some(callee) == tcx.lang_items().from_generator_fn();
                 if is_async_block {
index cb9b4bcb77a8574ea8baa50bd54b1c3e95587de1..5eb7d7a91cc76d5aeec900c92f91fae4e038c6f6 100644 (file)
@@ -206,7 +206,8 @@ pub fn in_rvalue<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, rvalue: &Rvalue
         Rvalue::Use(operand)
         | Rvalue::Repeat(operand, _)
         | Rvalue::UnaryOp(_, operand)
-        | Rvalue::Cast(_, operand, _) => in_operand::<Q, _>(cx, in_local, operand),
+        | Rvalue::Cast(_, operand, _)
+        | Rvalue::ShallowInitBox(operand, _) => in_operand::<Q, _>(cx, in_local, operand),
 
         Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
             in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
index 52d04cb4ff1e0f689a6794e6d5d7631b4ece72fd..9408dfa956b40c2d799f765514fbcbf4050fd19d 100644 (file)
@@ -523,6 +523,8 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
                 NullOp::AlignOf => {}
             },
 
+            Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
+
             Rvalue::UnaryOp(op, operand) => {
                 match op {
                     // These operations can never fail.
index bc13ca26e2e22059d24130eb298a38f2b8d409c5..49962570129704a91392ec7117e379e53d0aa040 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_data_structures"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index e2cbb09ce5e6d29e54c70975f4ff5c49f5903298..d8ac815a15821c114860dca527a26e9fdd62c87e 100644 (file)
@@ -3,7 +3,7 @@
 //! Also computes as the resulting DAG if each SCC is replaced with a
 //! node in the graph. This uses [Tarjan's algorithm](
 //! https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
-//! that completes in *O(n)* time.
+//! that completes in *O*(*n*) time.
 
 use crate::fx::FxHashSet;
 use crate::graph::vec_graph::VecGraph;
index dd6a17b92aef303b85fc4eae0e0b6391e86b5d63..b1f04bfbf0a848993e327fd4a7c07ce037422f5f 100644 (file)
@@ -18,7 +18,6 @@
 #![feature(extend_one)]
 #![feature(hash_raw_entry)]
 #![feature(in_band_lifetimes)]
-#![feature(iter_map_while)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
 #![feature(never_type)]
index 9a28f8f4e21062d5040d9acec2c8da20150b950f..20e2a3b9696e8560cb80d71d50cd9d8d6a0c281d 100644 (file)
@@ -9,7 +9,7 @@
 pub use index_map::SortedIndexMultiMap;
 
 /// `SortedMap` is a data structure with similar characteristics as BTreeMap but
-/// slightly different trade-offs: lookup, insertion, and removal are O(log(N))
+/// slightly different trade-offs: lookup, insertion, and removal are *O*(log(*n*))
 /// and elements can be iterated in order cheaply.
 ///
 /// `SortedMap` can be faster than a `BTreeMap` for small sizes (<50) since it
index 30f659c2f71bd209946b6b94006f35eb235ccaa5..a1ffbae8b15f6dd7d3c02264ade7a1c2faf2d24d 100644 (file)
@@ -33,10 +33,11 @@ pub fn new(value: T) -> Self {
 
     #[track_caller]
     pub fn borrow(&self) -> MappedReadGuard<'_, T> {
-        ReadGuard::map(self.value.borrow(), |opt| match *opt {
-            None => panic!("attempted to read from stolen value"),
-            Some(ref v) => v,
-        })
+        let borrow = self.value.borrow();
+        if let None = &*borrow {
+            panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
+        }
+        ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
     }
 
     #[track_caller]
index ba8616cc6ef73cb9340001bd3e99d1385c9e566c..6721e00027d42383889284dc3898a919827e2a06 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_driver"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 crate-type = ["dylib"]
index 270e5301895a44852cbfd652d63849324e504529..7d5f3e4672a0fe57bf28d2c2210579b4d29232ca 100644 (file)
@@ -1,4 +1,4 @@
 [package]
 name = "rustc_error_codes"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
index c74fd60e530c1f037de179c82c4d5ccca648f893..4846dc43605f8f0f07be62f63f3afbb7030c7f52 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_errors"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index b1526cf78d2e9c9d504e2235ec80241c5dfe6891..60a48b5a2d9c17ecf6e4ce6ba253007f5f015c80 100644 (file)
 #[macro_use]
 extern crate rustc_macros;
 
+#[macro_use]
+extern crate tracing;
+
 pub use emitter::ColorConfig;
 
-use tracing::debug;
 use Level::*;
 
 use emitter::{is_case_difference, Emitter, EmitterWriter};
@@ -1028,15 +1030,13 @@ fn print_error_count(&mut self, registry: &Registry) {
             let mut error_codes = self
                 .emitted_diagnostic_codes
                 .iter()
-                .filter_map(|x| {
-                    match &x {
+                .filter_map(|x| match &x {
                     DiagnosticId::Error(s)
-                        if let Ok(Some(_explanation)) = registry.try_find_description(s) =>
+                        if registry.try_find_description(s).map_or(false, |o| o.is_some()) =>
                     {
                         Some(s.clone())
                     }
                     _ => None,
-                }
                 })
                 .collect::<Vec<_>>();
             if !error_codes.is_empty() {
index 1be9321e4fed5a551d98938b5803e74f1be3df29..45237ab2e9f2502b32f48afd13dbf582c9e7c7a7 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_expand"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 build = false
 
 [lib]
index 60d653ac8b6f9be426af54ac13c47fe76aaecf46..1c0b2a9b487611a17a15a272975b7dd293ea47b3 100644 (file)
@@ -3,6 +3,7 @@
 use rustc_ast::{token, Attribute, Inline, Item};
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_parse::new_parser_from_file;
+use rustc_parse::validate_attr;
 use rustc_session::parse::ParseSess;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
@@ -168,7 +169,25 @@ fn mod_file_path_from_attr(
     dir_path: &Path,
 ) -> Option<PathBuf> {
     // Extract path string from first `#[path = "path_string"]` attribute.
-    let path_string = sess.first_attr_value_str_by_name(attrs, sym::path)?.as_str();
+    let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
+    let path_string = match first_path.value_str() {
+        Some(s) => s.as_str(),
+        None => {
+            // This check is here mainly to catch attempting to use a macro,
+            // such as #[path = concat!(...)]. This isn't currently supported
+            // because otherwise the InvocationCollector would need to defer
+            // loading a module until the #[path] attribute was expanded, and
+            // it doesn't support that (and would likely add a bit of
+            // complexity). Usually bad forms are checked in AstValidator (via
+            // `check_builtin_attribute`), but by the time that runs the macro
+            // is expanded, and it doesn't give an error.
+            validate_attr::emit_fatal_malformed_builtin_attribute(
+                &sess.parse_sess,
+                first_path,
+                sym::path,
+            );
+        }
+    };
 
     // On windows, the base path might have the form
     // `\\?\foo\bar` in which case it does not tolerate
index 52b60c3047e1c9180ac3d314b6f3b5e666f91ef8..5cb97198765fe4411a8e691f1990e7e9e2a850c6 100644 (file)
@@ -577,7 +577,7 @@ fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
             }
 
             // Synthesize a new symbol that includes the minus sign.
-            let symbol = Symbol::intern(&s[..1 + lit.symbol.len()]);
+            let symbol = Symbol::intern(&s[..1 + lit.symbol.as_str().len()]);
             lit = token::Lit::new(lit.kind, symbol, lit.suffix);
         }
 
index ee381e34251b54e5bf282026e9ad0b8fb90a0618..3d8d0db20d122d8decb88ac75fa6b48a083d3c05 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_feature"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 61e27d2e4cd41053db35dc55d60c8effeabdc63b..69e0e3a0136677b59de5970e43d7849cca86d8cd 100644 (file)
@@ -295,6 +295,8 @@ macro_rules! declare_features {
     (accepted, const_fn_union, "1.56.0", Some(51909), None),
     /// Allows explicit discriminants on non-unit enum variants.
     (accepted, arbitrary_enum_discriminant, "1.56.0", Some(60553), None),
+    /// Allows macro attributes to observe output of `#[derive]`.
+    (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
index efa93c186363a1570e100b657ecf8a8afbe3490e..f8b865e615c2ede9512c906de92add62df4dde73 100644 (file)
@@ -592,9 +592,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Lessens the requirements for structs to implement `Unsize`.
     (active, relaxed_struct_unsize, "1.51.0", Some(81793), None),
 
-    /// Allows macro attributes to observe output of `#[derive]`.
-    (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
-
     /// Allows associated types in inherent impls.
     (incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
 
@@ -675,6 +672,12 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows `let...else` statements.
     (active, let_else, "1.56.0", Some(87335), None),
 
+    /// Allows the `#[must_not_suspend]` attribute.
+    (active, must_not_suspend, "1.57.0", Some(83310), None),
+
+    /// Allows `#[track_caller]` on closures and generators.
+    (active, closure_track_caller, "1.57.0", Some(87417), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
index f74ea0e0c4d271c979df7f85c251922e1eb59f12..f3eaf2645f50acd7db135ac70f767ff90b3d155f 100644 (file)
@@ -202,6 +202,10 @@ macro_rules! experimental {
     ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(must_use, Normal, template!(Word, NameValueStr: "reason")),
+    gated!(
+        must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), must_not_suspend,
+        experimental!(must_not_suspend)
+    ),
     // FIXME(#14407)
     ungated!(
         deprecated, Normal,
index c417e978b311de92007fc70f584e8169dfe87b91..34c3fe2a005c81ae4ead69a38b967107ee8635c2 100644 (file)
@@ -1,4 +1,4 @@
 [package]
 name = "rustc_fs_util"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
index 87c41ae171ef5b361a07be97ee70353c0493ffcd..d657fdb1a778947df30d8c013138df5c075a9a87 100644 (file)
@@ -1,4 +1,4 @@
 [package]
 name = "rustc_graphviz"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
index 61b941fd756fc6045a5069b081099768cbf45a0b..3b6e6db72d1f7128e42a099c2c2fef6001e9c5f1 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_hir"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 3e8b98e9f5493dd146664a8f2820670e56530aaa..f07e52e04daa9d8020ee9b6ee58c2d6f72de845f 100644 (file)
@@ -28,9 +28,9 @@ macro_rules! arena_types {
             [] pat_field: rustc_hir::PatField<$tcx>,
             [] fn_decl: rustc_hir::FnDecl<$tcx>,
             [] foreign_item: rustc_hir::ForeignItem<$tcx>,
-            [few] foreign_item_ref: rustc_hir::ForeignItemRef<$tcx>,
+            [few] foreign_item_ref: rustc_hir::ForeignItemRef,
             [] impl_item: rustc_hir::ImplItem<$tcx>,
-            [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
+            [] impl_item_ref: rustc_hir::ImplItemRef,
             [] item: rustc_hir::Item<$tcx>,
             [few] inline_asm: rustc_hir::InlineAsm<$tcx>,
             [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
index f5fc693ce2556f90a3f9817b1968f30e0c6f606e..05b652fd5af2c4245dd6d727e7b9c4ef0a941abc 100644 (file)
@@ -2745,7 +2745,7 @@ pub enum ItemKind<'hir> {
     /// A module.
     Mod(Mod<'hir>),
     /// An external module, e.g. `extern { .. }`.
-    ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] },
+    ForeignMod { abi: Abi, items: &'hir [ForeignItemRef] },
     /// Module-level inline assembly (from `global_asm!`).
     GlobalAsm(&'hir InlineAsm<'hir>),
     /// A type alias, e.g., `type Foo = Bar<u8>`.
@@ -2782,7 +2782,7 @@ pub struct Impl<'hir> {
     pub of_trait: Option<TraitRef<'hir>>,
 
     pub self_ty: &'hir Ty<'hir>,
-    pub items: &'hir [ImplItemRef<'hir>],
+    pub items: &'hir [ImplItemRef],
 }
 
 impl ItemKind<'_> {
@@ -2846,13 +2846,12 @@ pub struct TraitItemRef {
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
 #[derive(Debug, HashStable_Generic)]
-pub struct ImplItemRef<'hir> {
+pub struct ImplItemRef {
     pub id: ImplItemId,
     #[stable_hasher(project(name))]
     pub ident: Ident,
     pub kind: AssocItemKind,
     pub span: Span,
-    pub vis: Visibility<'hir>,
     pub defaultness: Defaultness,
 }
 
@@ -2886,12 +2885,11 @@ pub fn hir_id(&self) -> HirId {
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
 #[derive(Debug, HashStable_Generic)]
-pub struct ForeignItemRef<'hir> {
+pub struct ForeignItemRef {
     pub id: ForeignItemId,
     #[stable_hasher(project(name))]
     pub ident: Ident,
     pub span: Span,
-    pub vis: Visibility<'hir>,
 }
 
 #[derive(Debug)]
index 137782a6dc78dcf809b196cd9dc0b447017d7eb4..1ac2625dd475483edce4e66030a81f5f222eb741 100644 (file)
@@ -392,10 +392,10 @@ fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
     fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) {
         walk_impl_item(self, ii)
     }
-    fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef<'v>) {
+    fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) {
         walk_foreign_item_ref(self, ii)
     }
-    fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef<'v>) {
+    fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
         walk_impl_item_ref(self, ii)
     }
     fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) {
@@ -1042,22 +1042,20 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
 
 pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
     visitor: &mut V,
-    foreign_item_ref: &'v ForeignItemRef<'v>,
+    foreign_item_ref: &'v ForeignItemRef,
 ) {
     // N.B., deliberately force a compilation error if/when new fields are added.
-    let ForeignItemRef { id, ident, span: _, ref vis } = *foreign_item_ref;
+    let ForeignItemRef { id, ident, span: _ } = *foreign_item_ref;
     visitor.visit_nested_foreign_item(id);
     visitor.visit_ident(ident);
-    visitor.visit_vis(vis);
 }
 
-pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef<'v>) {
+pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
     // N.B., deliberately force a compilation error if/when new fields are added.
-    let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;
+    let ImplItemRef { id, ident, ref kind, span: _, ref defaultness } = *impl_item_ref;
     visitor.visit_nested_impl_item(id);
     visitor.visit_ident(ident);
     visitor.visit_associated_item_kind(kind);
-    visitor.visit_vis(vis);
     visitor.visit_defaultness(defaultness);
 }
 
index c7510b7ec1422d2e9a66d72adb87cfb124083333..46a8e7deeed047bcccd932c9f7cd501201c3c312 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_hir_pretty"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 9156243a10c0a50d9f43354595e3fce09c0feba2..dece752c1945f693bdd40129d41b019f699ac441 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_incremental"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index e1a2b619763f23516839018d21d853319945b22e..b984a1321e0aa06e0e7e4887d899ce2a3152ef0d 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_index"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index aeb3f9970ab9e6a0cda3cb926d1dc54117c30818..5b1add4cfc6117c65baf25e3da754f4699c237a8 100644 (file)
@@ -1072,13 +1072,9 @@ pub fn new(num_columns: usize) -> Self {
     }
 
     fn ensure_row(&mut self, row: R) -> &mut HybridBitSet<C> {
-        // Instantiate any missing rows up to and including row `row` with an
-        // empty HybridBitSet.
-        self.rows.ensure_contains_elem(row, || None);
-
+        // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet.
         // Then replace row `row` with a full HybridBitSet if necessary.
-        let num_columns = self.num_columns;
-        self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns))
+        self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns))
     }
 
     /// Sets the cell at `(row, column)` to true. Put another way, insert
index 246fa28d986e5b59c52a613a5d1ef14235cfd595..8535a7c866d96bb255a9565cf4195b1c46161778 100644 (file)
@@ -720,6 +720,21 @@ pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
     }
 }
 
+/// `IndexVec` is often used as a map, so it provides some map-like APIs.
+impl<I: Idx, T> IndexVec<I, Option<T>> {
+    #[inline]
+    pub fn insert(&mut self, index: I, value: T) -> Option<T> {
+        self.ensure_contains_elem(index, || None);
+        self[index].replace(value)
+    }
+
+    #[inline]
+    pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
+        self.ensure_contains_elem(index, || None);
+        self[index].get_or_insert_with(value)
+    }
+}
+
 impl<I: Idx, T: Clone> IndexVec<I, T> {
     #[inline]
     pub fn resize(&mut self, new_len: usize, value: T) {
index 15649bb678e244d6c227ea4e00560067457cad14..f87ea43b1a72c8720360eedbec17d6e42b5b733d 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_infer"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 6a97a6c43c11e564ef12427fc7aa15225aafc1e4..b5c0307255771d3a4d9da59c21e6ca98df076488 100644 (file)
@@ -669,8 +669,10 @@ fn push_outlives(
         self.obligations.push(Obligation {
             cause: self.cause.clone(),
             param_env: self.param_env,
-            predicate: ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
-                .to_predicate(self.infcx.tcx),
+            predicate: ty::Binder::dummy(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
+                sup, sub,
+            )))
+            .to_predicate(self.infcx.tcx),
             recursion_depth: 0,
         });
     }
index a0ee212bed0cd5df3d1360950b38e3413296169e..3f54247ecef211bcd48e6e621b05d39037193e15 100644 (file)
@@ -22,6 +22,7 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
+use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
@@ -29,7 +30,6 @@
 use super::unify_key::replace_if_possible;
 use super::unify_key::{ConstVarValue, ConstVariableValue};
 use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use super::{equate::Equate, type_variable::Diverging};
 use super::{InferCtxt, MiscVariable, TypeTrace};
 
 use crate::traits::{Obligation, PredicateObligations};
@@ -360,7 +360,8 @@ pub fn instantiate(
             self.obligations.push(Obligation::new(
                 self.trace.cause.clone(),
                 self.param_env,
-                ty::PredicateKind::WellFormed(b_ty.into()).to_predicate(self.infcx.tcx),
+                ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into()))
+                    .to_predicate(self.infcx.tcx),
             ));
         }
 
@@ -463,7 +464,7 @@ pub fn add_const_equate_obligation(
         self.obligations.push(Obligation::new(
             self.trace.cause.clone(),
             self.param_env,
-            predicate.to_predicate(self.tcx()),
+            ty::Binder::dummy(predicate).to_predicate(self.tcx()),
         ));
     }
 }
@@ -645,7 +646,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                                 .inner
                                 .borrow_mut()
                                 .type_variables()
-                                .new_var(self.for_universe, Diverging::NotDiverging, origin);
+                                .new_var(self.for_universe, origin);
                             let u = self.tcx().mk_ty_var(new_var_id);
 
                             // Record that we replaced `vid` with `new_var_id` as part of a generalization
@@ -885,11 +886,12 @@ fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
 
                         let origin =
                             *self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
-                        let new_var_id = self.infcx.inner.borrow_mut().type_variables().new_var(
-                            self.for_universe,
-                            Diverging::NotDiverging,
-                            origin,
-                        );
+                        let new_var_id = self
+                            .infcx
+                            .inner
+                            .borrow_mut()
+                            .type_variables()
+                            .new_var(self.for_universe, origin);
                         let u = self.tcx().mk_ty_var(new_var_id);
                         debug!(
                             "ConstInferUnifier: replacing original vid={:?} with new={:?}",
index b8089b2499b66524bef2f6ef2da45291c4e6af9c..d9b7022f03ac1a9ac2e74e61e87f1b22b2556963 100644 (file)
@@ -7,7 +7,7 @@
 //! inference graph arose so that we can explain to the user what gave
 //! rise to a particular error.
 //!
-//! The basis of the system are the "origin" types. An "origin" is the
+//! The system is based around a set of "origin" types. An "origin" is the
 //! reason that a constraint or inference variable arose. There are
 //! different "origin" enums for different kinds of constraints/variables
 //! (e.g., `TypeOrigin`, `RegionVariableOrigin`). An origin always has
index 354b8e26d53d5dcaa466a9adc0208f598bfa3a85..632e792bbd1acadccd66b06465116facb2ee18a1 100644 (file)
@@ -46,7 +46,7 @@
 use self::region_constraints::{
     RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
 };
-use self::type_variable::{Diverging, TypeVariableOrigin, TypeVariableOriginKind};
+use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
@@ -64,6 +64,7 @@
 pub mod nll_relate;
 pub mod opaque_types;
 pub mod outlives;
+mod projection;
 pub mod region_constraints;
 pub mod resolve;
 mod sub;
@@ -701,17 +702,6 @@ pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
         t.fold_with(&mut self.freshener())
     }
 
-    /// Returns whether `ty` is a diverging type variable or not.
-    /// (If `ty` is not a type variable at all, returns not diverging.)
-    ///
-    /// No attempt is made to resolve `ty`.
-    pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> Diverging {
-        match *ty.kind() {
-            ty::Infer(ty::TyVar(vid)) => self.inner.borrow_mut().type_variables().var_diverges(vid),
-            _ => Diverging::NotDiverging,
-        }
-    }
-
     /// Returns the origin of the type variable identified by `vid`, or `None`
     /// if this is not a type variable.
     ///
@@ -1070,12 +1060,17 @@ pub fn region_outlives_predicate(
         })
     }
 
-    pub fn next_ty_var_id(&self, diverging: Diverging, origin: TypeVariableOrigin) -> TyVid {
-        self.inner.borrow_mut().type_variables().new_var(self.universe(), diverging, origin)
+    /// Number of type variables created so far.
+    pub fn num_ty_vars(&self) -> usize {
+        self.inner.borrow_mut().type_variables().num_vars()
+    }
+
+    pub fn next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid {
+        self.inner.borrow_mut().type_variables().new_var(self.universe(), origin)
     }
 
     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::NotDiverging, origin))
+        self.tcx.mk_ty_var(self.next_ty_var_id(origin))
     }
 
     pub fn next_ty_var_in_universe(
@@ -1083,18 +1078,10 @@ pub fn next_ty_var_in_universe(
         origin: TypeVariableOrigin,
         universe: ty::UniverseIndex,
     ) -> Ty<'tcx> {
-        let vid = self.inner.borrow_mut().type_variables().new_var(
-            universe,
-            Diverging::NotDiverging,
-            origin,
-        );
+        let vid = self.inner.borrow_mut().type_variables().new_var(universe, origin);
         self.tcx.mk_ty_var(vid)
     }
 
-    pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::Diverges, origin))
-    }
-
     pub fn next_const_var(
         &self,
         ty: Ty<'tcx>,
@@ -1206,7 +1193,6 @@ pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg
                 // as the substitutions for the default, `(T, U)`.
                 let ty_var_id = self.inner.borrow_mut().type_variables().new_var(
                     self.universe(),
-                    Diverging::NotDiverging,
                     TypeVariableOrigin {
                         kind: TypeVariableOriginKind::TypeParameterDefinition(
                             param.name,
index e88c6608aca335540020bb44f498298afd00345a..73d74584a5e13db33c74ced5712e7d8b7427eed4 100644 (file)
@@ -22,7 +22,6 @@
 //!   constituents)
 
 use crate::infer::combine::ConstEquateRelation;
-use crate::infer::type_variable::Diverging;
 use crate::infer::InferCtxt;
 use crate::infer::{ConstVarValue, ConstVariableValue};
 use rustc_data_structures::fx::FxHashMap;
@@ -927,8 +926,7 @@ fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                             // Replacing with a new variable in the universe `self.universe`,
                             // it will be unified later with the original type variable in
                             // the universe `_universe`.
-                            let new_var_id =
-                                variables.new_var(self.universe, Diverging::NotDiverging, origin);
+                            let new_var_id = variables.new_var(self.universe, origin);
 
                             let u = self.tcx().mk_ty_var(new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
new file mode 100644 (file)
index 0000000..9b53ab7
--- /dev/null
@@ -0,0 +1,39 @@
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::{self, ToPredicate, Ty};
+
+use crate::traits::{Obligation, PredicateObligation};
+
+use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use super::InferCtxt;
+
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
+    /// Instead of normalizing an associated type projection,
+    /// this function generates an inference variable and registers
+    /// an obligation that this inference variable must be the result
+    /// of the given projection. This allows us to proceed with projections
+    /// while they cannot be resolved yet due to missing information or
+    /// simply due to the lack of access to the trait resolution machinery.
+    pub fn infer_projection(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        projection_ty: ty::ProjectionTy<'tcx>,
+        cause: ObligationCause<'tcx>,
+        recursion_depth: usize,
+        obligations: &mut Vec<PredicateObligation<'tcx>>,
+    ) -> Ty<'tcx> {
+        let def_id = projection_ty.item_def_id;
+        let ty_var = self.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::NormalizeProjectionType,
+            span: self.tcx.def_span(def_id),
+        });
+        let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
+        let obligation = Obligation::with_depth(
+            cause,
+            recursion_depth,
+            param_env,
+            projection.to_predicate(self.tcx),
+        );
+        obligations.push(obligation);
+        ty_var
+    }
+}
index 1692d8ee526d0519474eed4c1016d6715a30130b..8ef0d132cf09fc5692a956adcd3c0c9bfe0da086 100644 (file)
@@ -97,11 +97,11 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                 self.fields.obligations.push(Obligation::new(
                     self.fields.trace.cause.clone(),
                     self.fields.param_env,
-                    ty::PredicateKind::Subtype(ty::SubtypePredicate {
+                    ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
                         a_is_expected: self.a_is_expected,
                         a,
                         b,
-                    })
+                    }))
                     .to_predicate(self.tcx()),
                 ));
 
index f15268f6895efa8b92dba07373fc30057997abff..0e832685310d51b687d225f2fdb5139359f28383 100644 (file)
@@ -129,19 +129,16 @@ pub enum TypeVariableOriginKind {
     SubstitutionPlaceholder,
     AutoDeref,
     AdjustmentType,
-    DivergingFn,
+
+    /// In type check, when we are type checking a function that
+    /// returns `-> dyn Foo`, we substitute a type variable for the
+    /// return type for diagnostic purposes.
+    DynReturnFn,
     LatticeVariable,
 }
 
 pub(crate) struct TypeVariableData {
     origin: TypeVariableOrigin,
-    diverging: Diverging,
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum Diverging {
-    NotDiverging,
-    Diverges,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -191,14 +188,6 @@ pub(crate) fn with_log<'a>(
 }
 
 impl<'tcx> TypeVariableTable<'_, 'tcx> {
-    /// Returns the diverges flag given when `vid` was created.
-    ///
-    /// Note that this function does not return care whether
-    /// `vid` has been unified with something else or not.
-    pub fn var_diverges(&self, vid: ty::TyVid) -> Diverging {
-        self.storage.values.get(vid.index()).diverging
-    }
-
     /// Returns the origin that was given when `vid` was created.
     ///
     /// Note that this function does not return care whether
@@ -260,7 +249,6 @@ pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
     pub fn new_var(
         &mut self,
         universe: ty::UniverseIndex,
-        diverging: Diverging,
         origin: TypeVariableOrigin,
     ) -> ty::TyVid {
         let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe });
@@ -268,13 +256,10 @@ pub fn new_var(
         let sub_key = self.sub_relations().new_key(());
         assert_eq!(eq_key.vid, sub_key);
 
-        let index = self.values().push(TypeVariableData { origin, diverging });
+        let index = self.values().push(TypeVariableData { origin });
         assert_eq!(eq_key.vid.as_u32(), index as u32);
 
-        debug!(
-            "new_var(index={:?}, universe={:?}, diverging={:?}, origin={:?}",
-            eq_key.vid, universe, diverging, origin,
-        );
+        debug!("new_var(index={:?}, universe={:?}, origin={:?}", eq_key.vid, universe, origin,);
 
         eq_key.vid
     }
index 42333dc29bc7c37ae50cebb27616d19f280fc02b..dce4a87b041189a49910765f763ef7798d781a77 100644 (file)
@@ -1,5 +1,6 @@
 use crate::infer::InferCtxt;
 use crate::traits::Obligation;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness};
@@ -34,7 +35,7 @@ fn register_bound(
                 cause,
                 recursion_depth: 0,
                 param_env,
-                predicate: trait_ref.without_const().to_predicate(infcx.tcx),
+                predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
             },
         );
     }
@@ -73,6 +74,8 @@ fn select_with_constness_where_possible(
     }
 
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
+
+    fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
 }
 
 pub trait TraitEngineExt<'tcx> {
index 3a25cb66896d510c751911d94efaba2d1ff6cb91..30d5613d5820d8664817bab71e3ed0d836ada1f1 100644 (file)
@@ -231,6 +231,7 @@ fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
                                 None
                             }
                         })
+                        .map(ty::Binder::dummy)
                         .map(|predicate_kind| predicate_kind.to_predicate(tcx))
                         .filter(|&predicate| visited.insert(predicate))
                         .map(|predicate| {
index e76fa6d8a1bc664b7002a429e18e6ff797dc3e06..07af2201f5fc2a1222dc428abafc523957d1d3d7 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_interface"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index c7424b9e2a120560a39c506abd23157056f73470..2fc3759968fd3531d8c63857a98cbda411de3a00 100644 (file)
@@ -1,6 +1,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(internal_output_capture)]
+#![feature(thread_spawn_unchecked)]
 #![feature(nll)]
 #![feature(once_cell)]
 #![recursion_limit = "256"]
index cb7529b527e8f885e322afd9c9988c40f6a0c5f5..0a6d76c99b77a0636650a62682a56210ab9a2deb 100644 (file)
@@ -23,7 +23,7 @@
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
 use rustc_mir_build as mir_build;
-use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
+use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
 use rustc_passes::{self, hir_stats, layout_test};
 use rustc_plugin_impl as plugin;
 use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
@@ -33,8 +33,8 @@
 use rustc_session::lint;
 use rustc_session::output::{filename_for_input, filename_for_metadata};
 use rustc_session::search_paths::PathKind;
-use rustc_session::Session;
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_session::{Limit, Session};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::FileName;
 use rustc_trait_selection::traits;
 use rustc_typeck as typeck;
@@ -311,8 +311,7 @@ pub fn configure_and_expand(
 
         // Create the config for macro expansion
         let features = sess.features_untracked();
-        let recursion_limit =
-            rustc_middle::middle::limits::get_recursion_limit(&krate.attrs, &sess);
+        let recursion_limit = get_recursion_limit(&krate.attrs, &sess);
         let cfg = rustc_expand::expand::ExpansionConfig {
             features: Some(&features),
             recursion_limit,
@@ -1070,3 +1069,24 @@ pub fn start_codegen<'tcx>(
 
     codegen
 }
+
+fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
+    if let Some(attr) = krate_attrs
+        .iter()
+        .find(|attr| attr.has_name(sym::recursion_limit) && attr.value_str().is_none())
+    {
+        // This is here mainly to check for using a macro, such as
+        // #![recursion_limit = foo!()]. That is not supported since that
+        // would require expanding this while in the middle of expansion,
+        // which needs to know the limit before expanding. Otherwise,
+        // validation would normally be caught in AstValidator (via
+        // `check_builtin_attribute`), but by the time that runs the macro
+        // is expanded, and it doesn't give an error.
+        validate_attr::emit_fatal_malformed_builtin_attribute(
+            &sess.parse_sess,
+            attr,
+            sym::recursion_limit,
+        );
+    }
+    rustc_middle::middle::limits::get_recursion_limit(krate_attrs, sess)
+}
index a5f0c01477898dd6b2248a078026687c7b4338ad..a1d1b63c8fafe8a034bbb721fb5a1b20f8e80fe7 100644 (file)
@@ -10,6 +10,7 @@
 use rustc_metadata::dynamic_lib::DynamicLibrary;
 #[cfg(parallel_compiler)]
 use rustc_middle::ty::tls;
+use rustc_parse::validate_attr;
 #[cfg(parallel_compiler)]
 use rustc_query_impl::QueryCtxt;
 use rustc_resolve::{self, Resolver};
@@ -115,24 +116,11 @@ fn get_stack_size() -> Option<usize> {
 /// for `'static` bounds.
 #[cfg(not(parallel_compiler))]
 pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
-    struct Ptr(*mut ());
-    unsafe impl Send for Ptr {}
-    unsafe impl Sync for Ptr {}
-
-    let mut f = Some(f);
-    let run = Ptr(&mut f as *mut _ as *mut ());
-    let mut result = None;
-    let result_ptr = Ptr(&mut result as *mut _ as *mut ());
-
-    let thread = cfg.spawn(move || {
-        let run = unsafe { (*(run.0 as *mut Option<F>)).take().unwrap() };
-        let result = unsafe { &mut *(result_ptr.0 as *mut Option<R>) };
-        *result = Some(run());
-    });
-
-    match thread.unwrap().join() {
-        Ok(()) => result.unwrap(),
-        Err(p) => panic::resume_unwind(p),
+    // SAFETY: join() is called immediately, so any closure captures are still
+    // alive.
+    match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
+        Ok(v) => v,
+        Err(e) => panic::resume_unwind(e),
     }
 }
 
@@ -488,7 +476,7 @@ pub fn get_codegen_sysroot(
 }
 
 pub(crate) fn check_attr_crate_type(
-    _sess: &Session,
+    sess: &Session,
     attrs: &[ast::Attribute],
     lint_buffer: &mut LintBuffer,
 ) {
@@ -528,6 +516,19 @@ pub(crate) fn check_attr_crate_type(
                         );
                     }
                 }
+            } else {
+                // This is here mainly to check for using a macro, such as
+                // #![crate_type = foo!()]. That is not supported since the
+                // crate type needs to be known very early in compilation long
+                // before expansion. Otherwise, validation would normally be
+                // caught in AstValidator (via `check_builtin_attribute`), but
+                // by the time that runs the macro is expanded, and it doesn't
+                // give an error.
+                validate_attr::emit_fatal_malformed_builtin_attribute(
+                    &sess.parse_sess,
+                    a,
+                    sym::crate_type,
+                );
             }
         }
     }
index 7e05fe545cabe580987dd4092fffefe67eb7b6cb..60c146f457b42afc0dcd2f849d1aba70476f7836 100644 (file)
@@ -2,7 +2,7 @@
 name = "rustc_lexer"
 version = "0.1.0"
 license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
 
 repository = "https://github.com/rust-lang/rust/"
 description = """
index 8294d5878fa99015efaee012ac8a5eb2c049fe22..414fcbeb9e415d57706461952f1a126fcbce78df 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_lint"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 if_chain = "1.0"
index 5ac42c50c7240d22edb1adbd1b775248ac89d3fc..1facd973754331c08da5d1c4af5b92d801d29d2a 100644 (file)
@@ -13,7 +13,7 @@
     ///
     /// ### Example
     ///
-    /// ```rust
+    /// ```rust,edition2018
     /// # #![allow(unused)]
     /// [1, 2, 3].into_iter().for_each(|n| { *n; });
     /// ```
index 2850e7a6b44e95a485046701b98911e75a897ca3..e1bcc3aa52bc643dae02e9b7eed4385b0030c457 100644 (file)
@@ -1686,7 +1686,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
     ///
     /// ### Example
     ///
-    /// ```rust
+    /// ```rust,edition2018
     /// let x = 123;
     /// match x {
     ///     0...100 => {}
index ef4bda666ba062c7bb033084109649cda82bab23..10285272130cc2626ae7a53537a6a1d9858b9083 100644 (file)
@@ -298,6 +298,7 @@ macro_rules! register_passes {
         UNUSED_LABELS,
         UNUSED_PARENS,
         UNUSED_BRACES,
+        MUST_NOT_SUSPEND,
         REDUNDANT_SEMICOLONS
     );
 
index 33a6edafa26408185baf547c2bebb13b0e5bbab5..ae9c5ce5c3c2bdeff8c4f31dbecb81ebe128ce84 100644 (file)
@@ -18,7 +18,7 @@
     ///
     /// ### Example
     ///
-    /// ```rust,no_run
+    /// ```rust,no_run,edition2018
     /// panic!("{}");
     /// panic!(123);
     /// ```
index f9ada5cc95f58c8cd7759272ac48c68f7b8059ce..798d50819e2d8b8449c5a74c10e9e9e97aee2bd5 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_lint_defs"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 rustc_ast = { path = "../rustc_ast" }
index a00561e5213570ab7fa39eb60290a04c1b92b0a8..5830ce26fea3ff224d65dae692ed2c2febdff0e6 100644 (file)
     "imports that are never used"
 }
 
+declare_lint! {
+    /// The `must_not_suspend` lint guards against values that shouldn't be held across suspend points
+    /// (`.await`)
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![feature(must_not_suspend)]
+    ///
+    /// #[must_not_suspend]
+    /// struct SyncThing {}
+    ///
+    /// async fn yield_now() {}
+    ///
+    /// pub async fn uhoh() {
+    ///     let guard = SyncThing {};
+    ///     yield_now().await;
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]`
+    /// attribute being held across suspend points. A "suspend" point is usually a `.await` in an async
+    /// function.
+    ///
+    /// This attribute can be used to mark values that are semantically incorrect across suspends
+    /// (like certain types of timers), values that have async alternatives, and values that
+    /// regularly cause problems with the `Send`-ness of async fn's returned futures (like
+    /// `MutexGuard`'s)
+    ///
+    pub MUST_NOT_SUSPEND,
+    Warn,
+    "use of a `#[must_not_suspend]` value across a yield point",
+}
+
 declare_lint! {
     /// The `unused_extern_crates` lint guards against `extern crate` items
     /// that are never used.
     ///
     /// ### Example
     ///
-    /// ```rust
+    /// ```rust,edition2018
     /// trait Trait { }
     ///
     /// fn takes_trait_object(_: Box<Trait>) {
         CENUM_IMPL_DROP_CAST,
         CONST_EVALUATABLE_UNCHECKED,
         INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
+        MUST_NOT_SUSPEND,
         UNINHABITED_STATIC,
         FUNCTION_ITEM_REFERENCES,
         USELESS_DEPRECATED,
     ///
     /// ### Example
     ///
-    /// ```rust,compile_fail
+    /// ```rust,edition2018,compile_fail
     /// #![deny(rust_2021_prefixes_incompatible_syntax)]
     ///
     /// macro_rules! m {
     ///
     /// This lint suggests to add whitespace between the `z` and `"hey"` tokens
     /// to keep them separated in Rust 2021.
+    // Allow this lint -- rustdoc doesn't yet support threading edition into this lint's parser.
+    #[allow(rustdoc::invalid_rust_codeblocks)]
     pub RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
     Allow,
     "identifiers that will be parsed as a prefix in Rust 2021",
index 2f0f3dd9ecbb9eaf8e7e316a03d7434a73a7d7d5..d8dfcc84e68da444575638816b3ae1ba5a104718 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_llvm"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [features]
 static-libstdcpp = []
index 8dbacd71fc13892ee3877fa6ac4e987875de97ba..48eb50953a957dc759f4e867a9a3564c9fe6a192 100644 (file)
@@ -1004,7 +1004,10 @@ LLVMRustOptimizeWithNewPassManager(
 #endif
   bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
   if (!NoPrepopulatePasses) {
-    if (OptLevel == OptimizationLevel::O0) {
+    // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
+    // At the same time, the LTO pipelines do support O0 and using them is required.
+    bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
+    if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
 #if LLVM_VERSION_GE(12, 0)
       for (const auto &C : PipelineStartEPCallbacks)
         PB.registerPipelineStartEPCallback(C);
@@ -1747,7 +1750,7 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
 // the comment in `back/lto.rs` for why this exists.
 extern "C" void
-LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
+LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
                                 DICompileUnit **A,
                                 DICompileUnit **B) {
   Module *M = unwrap(Mod);
@@ -1765,7 +1768,7 @@ LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
 // the comment in `back/lto.rs` for why this exists.
 extern "C" void
-LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
+LLVMRustLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
   Module *M = unwrap(Mod);
 
   // If the original source module didn't have a `DICompileUnit` then try to
index e4dddbab06755245143214d8772b8d05718a5a73..a9192be4d6ef43f00574dac372fc45970d74d0f4 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_macros"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 proc-macro = true
index 6b874aafa1017a2e96b3d5f121875755d7aec3ca..f71fefd17992083d4bd026199d7c3ca4e10e07fb 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_metadata"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index b8d22560618162bdbdf6a88b047b96b88b1cdc9a..6637dbd19013f91d16ab25b7896070c00af47101 100644 (file)
 //! should be used when linking each output type requested in this session. This
 //! generally follows this set of rules:
 //!
-//!     1. Each library must appear exactly once in the output.
-//!     2. Each rlib contains only one library (it's just an object file)
-//!     3. Each dylib can contain more than one library (due to static linking),
-//!        and can also bring in many dynamic dependencies.
+//! 1. Each library must appear exactly once in the output.
+//! 2. Each rlib contains only one library (it's just an object file)
+//! 3. Each dylib can contain more than one library (due to static linking),
+//!    and can also bring in many dynamic dependencies.
 //!
 //! With these constraints in mind, it's generally a very difficult problem to
 //! find a solution that's not "all rlibs" or "all dylibs". I have suspicions
 //!
 //! The current selection algorithm below looks mostly similar to:
 //!
-//!     1. If static linking is required, then require all upstream dependencies
-//!        to be available as rlibs. If not, generate an error.
-//!     2. If static linking is requested (generating an executable), then
-//!        attempt to use all upstream dependencies as rlibs. If any are not
-//!        found, bail out and continue to step 3.
-//!     3. Static linking has failed, at least one library must be dynamically
-//!        linked. Apply a heuristic by greedily maximizing the number of
-//!        dynamically linked libraries.
-//!     4. Each upstream dependency available as a dynamic library is
-//!        registered. The dependencies all propagate, adding to a map. It is
-//!        possible for a dylib to add a static library as a dependency, but it
-//!        is illegal for two dylibs to add the same static library as a
-//!        dependency. The same dylib can be added twice. Additionally, it is
-//!        illegal to add a static dependency when it was previously found as a
-//!        dylib (and vice versa)
-//!     5. After all dynamic dependencies have been traversed, re-traverse the
-//!        remaining dependencies and add them statically (if they haven't been
-//!        added already).
+//! 1. If static linking is required, then require all upstream dependencies
+//!    to be available as rlibs. If not, generate an error.
+//! 2. If static linking is requested (generating an executable), then
+//!    attempt to use all upstream dependencies as rlibs. If any are not
+//!    found, bail out and continue to step 3.
+//! 3. Static linking has failed, at least one library must be dynamically
+//!    linked. Apply a heuristic by greedily maximizing the number of
+//!    dynamically linked libraries.
+//! 4. Each upstream dependency available as a dynamic library is
+//!    registered. The dependencies all propagate, adding to a map. It is
+//!    possible for a dylib to add a static library as a dependency, but it
+//!    is illegal for two dylibs to add the same static library as a
+//!    dependency. The same dylib can be added twice. Additionally, it is
+//!    illegal to add a static dependency when it was previously found as a
+//!    dylib (and vice versa)
+//! 5. After all dynamic dependencies have been traversed, re-traverse the
+//!    remaining dependencies and add them statically (if they haven't been
+//!    added already).
 //!
 //! While not perfect, this algorithm should help support use-cases such as leaf
 //! dependencies being static while the larger tree of inner dependencies are
@@ -277,7 +277,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
     let all_crates_available_as_rlib = tcx
         .crates(())
         .iter()
-        .cloned()
+        .copied()
         .filter_map(|cnum| {
             if tcx.dep_kind(cnum).macros_only() {
                 return None;
@@ -291,10 +291,11 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
 
     // All crates are available in an rlib format, so we're just going to link
     // everything in explicitly so long as it's actually required.
-    let last_crate = tcx.crates(()).len();
-    let mut ret = (1..last_crate + 1)
-        .map(|cnum| {
-            if tcx.dep_kind(CrateNum::new(cnum)) == CrateDepKind::Explicit {
+    let mut ret = tcx
+        .crates(())
+        .iter()
+        .map(|&cnum| {
+            if tcx.dep_kind(cnum) == CrateDepKind::Explicit {
                 Linkage::Static
             } else {
                 Linkage::NotLinked
index 5f0d8c46f20dcd27eb0cb3a0972b9eb30a722ea1..5ad55dbf5c80d38ba9415413204d6aa34a9f3aea 100644 (file)
@@ -382,7 +382,7 @@ fn process_command_line(&mut self) {
         }
     }
 
-    fn i686_arg_list_size(&self, item: &hir::ForeignItemRef<'_>) -> usize {
+    fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize {
         let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions(
             self.tcx
                 .type_of(item.id.def_id)
@@ -406,7 +406,7 @@ fn i686_arg_list_size(&self, item: &hir::ForeignItemRef<'_>) -> usize {
             .sum()
     }
 
-    fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef<'_>) -> DllImport {
+    fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef) -> DllImport {
         let calling_convention = if self.tcx.sess.target.arch == "x86" {
             match abi {
                 Abi::C { .. } | Abi::Cdecl => DllCallingConvention::C,
index 70952d388d52d9fba6aed7960422085428600f43..7be0e32ef38dca3c9753defe7730ee817123e067 100644 (file)
@@ -304,17 +304,7 @@ pub fn provide(providers: &mut Providers) {
             // traversal, but not globally minimal across all crates.
             let bfs_queue = &mut VecDeque::new();
 
-            // Preferring shortest paths alone does not guarantee a
-            // deterministic result; so sort by crate num to avoid
-            // hashtable iteration non-determinism. This only makes
-            // things as deterministic as crate-nums assignment is,
-            // which is to say, its not deterministic in general. But
-            // we believe that libstd is consistently assigned crate
-            // num 1, so it should be enough to resolve #46112.
-            let mut crates: Vec<CrateNum> = (*tcx.crates(())).to_owned();
-            crates.sort();
-
-            for &cnum in crates.iter() {
+            for &cnum in tcx.crates(()) {
                 // Ignore crates without a corresponding local `extern crate` item.
                 if tcx.missing_extern_crate_item(cnum) {
                     continue;
@@ -323,35 +313,31 @@ pub fn provide(providers: &mut Providers) {
                 bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX });
             }
 
-            // (restrict scope of mutable-borrow of `visible_parent_map`)
-            {
-                let visible_parent_map = &mut visible_parent_map;
-                let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
-                    if child.vis != ty::Visibility::Public {
-                        return;
-                    }
+            let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
+                if child.vis != ty::Visibility::Public {
+                    return;
+                }
 
-                    if let Some(child) = child.res.opt_def_id() {
-                        match visible_parent_map.entry(child) {
-                            Entry::Occupied(mut entry) => {
-                                // If `child` is defined in crate `cnum`, ensure
-                                // that it is mapped to a parent in `cnum`.
-                                if child.is_local() && entry.get().is_local() {
-                                    entry.insert(parent);
-                                }
-                            }
-                            Entry::Vacant(entry) => {
+                if let Some(child) = child.res.opt_def_id() {
+                    match visible_parent_map.entry(child) {
+                        Entry::Occupied(mut entry) => {
+                            // If `child` is defined in crate `cnum`, ensure
+                            // that it is mapped to a parent in `cnum`.
+                            if child.is_local() && entry.get().is_local() {
                                 entry.insert(parent);
-                                bfs_queue.push_back(child);
                             }
                         }
+                        Entry::Vacant(entry) => {
+                            entry.insert(parent);
+                            bfs_queue.push_back(child);
+                        }
                     }
-                };
+                }
+            };
 
-                while let Some(def) = bfs_queue.pop_front() {
-                    for child in tcx.item_children(def).iter() {
-                        add_child(bfs_queue, child, def);
-                    }
+            while let Some(def) = bfs_queue.pop_front() {
+                for child in tcx.item_children(def).iter() {
+                    add_child(bfs_queue, child, def);
                 }
             }
 
index a50c4549d3d3fbe8a1334e73c3801d79ca08ee34..8509aa00bc0225de605385211c021cf16ab8f98e 100644 (file)
@@ -1708,9 +1708,10 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
 
     fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
         empty_proc_macro!(self);
-        let crates = self.tcx.crates(());
 
-        let mut deps = crates
+        let deps = self
+            .tcx
+            .crates(())
             .iter()
             .map(|&cnum| {
                 let dep = CrateDep {
@@ -1724,8 +1725,6 @@ fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
             })
             .collect::<Vec<_>>();
 
-        deps.sort_by_key(|&(cnum, _)| cnum);
-
         {
             // Sanity-check the crate numbers
             let mut expected_cnum = 1;
index 68b83fccc85fd4dd1f98c49996c1564c91a6732c..b1fcc34bee1d7d68884b397c8d817d1a9ada9115 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_middle"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 082948eba416d62c08714c36ac92d1b9be971e53..5ecb1c9b0ffcc3b62cf49b960178704dab9ea131 100644 (file)
@@ -413,18 +413,18 @@ fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
         self.visit_nested_trait_item(id);
     }
 
-    fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef<'hir>) {
+    fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
         // Do not visit the duplicate information in ImplItemRef. We want to
         // map the actual nodes, not the duplicate ones in the *Ref.
-        let ImplItemRef { id, ident: _, kind: _, span: _, vis: _, defaultness: _ } = *ii;
+        let ImplItemRef { id, ident: _, kind: _, span: _, defaultness: _ } = *ii;
 
         self.visit_nested_impl_item(id);
     }
 
-    fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef<'hir>) {
+    fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef) {
         // Do not visit the duplicate information in ForeignItemRef. We want to
         // map the actual nodes, not the duplicate ones in the *Ref.
-        let ForeignItemRef { id, ident: _, span: _, vis: _ } = *fi;
+        let ForeignItemRef { id, ident: _, span: _ } = *fi;
 
         self.visit_nested_foreign_item(id);
     }
index 0c2c653e92e9a72b0e5413ccdc0285416b171434..3707fadadac208cf774ce2363aa25582d66cd5fd 100644 (file)
@@ -83,12 +83,12 @@ pub struct Map<'hir> {
 
 /// An iterator that walks up the ancestor tree of a given `HirId`.
 /// Constructed using `tcx.hir().parent_iter(hir_id)`.
-pub struct ParentHirIterator<'map, 'hir> {
+pub struct ParentHirIterator<'hir> {
     current_id: HirId,
-    map: &'map Map<'hir>,
+    map: Map<'hir>,
 }
 
-impl<'hir> Iterator for ParentHirIterator<'_, 'hir> {
+impl<'hir> Iterator for ParentHirIterator<'hir> {
     type Item = (HirId, Node<'hir>);
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -115,12 +115,12 @@ fn next(&mut self) -> Option<Self::Item> {
 
 /// An iterator that walks up the ancestor tree of a given `HirId`.
 /// Constructed using `tcx.hir().parent_owner_iter(hir_id)`.
-pub struct ParentOwnerIterator<'map, 'hir> {
+pub struct ParentOwnerIterator<'hir> {
     current_id: HirId,
-    map: &'map Map<'hir>,
+    map: Map<'hir>,
 }
 
-impl<'hir> Iterator for ParentOwnerIterator<'_, 'hir> {
+impl<'hir> Iterator for ParentOwnerIterator<'hir> {
     type Item = (HirId, OwnerNode<'hir>);
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -588,13 +588,13 @@ fn par_iter_submodules<F>(tcx: TyCtxt<'_>, module: LocalDefId, f: &F)
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
     /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
-    pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> {
+    pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> {
         ParentHirIterator { current_id, map: self }
     }
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
     /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
-    pub fn parent_owner_iter(&self, current_id: HirId) -> ParentOwnerIterator<'_, 'hir> {
+    pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> {
         ParentOwnerIterator { current_id, map: self }
     }
 
index c7f58ce5b13371af578d7ce83203e2d667c36e06..4b4f65a062f6329d1a23b0b565062cec88382ef9 100644 (file)
@@ -1,9 +1,9 @@
 use crate::ich;
 use crate::middle::cstore::CrateStore;
-use crate::ty::{fast_reject, TyCtxt};
+use crate::ty::TyCtxt;
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
@@ -14,9 +14,6 @@
 use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
 
-use smallvec::SmallVec;
-use std::cmp::Ord;
-
 fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
     debug_assert!(!ich::IGNORED_ATTRIBUTES.is_empty());
     ich::IGNORED_ATTRIBUTES.iter().copied().collect()
@@ -241,39 +238,3 @@ fn span_data_to_lines_and_cols(
 }
 
 impl rustc_session::HashStableContext for StableHashingContext<'a> {}
-
-pub fn hash_stable_trait_impls<'a>(
-    hcx: &mut StableHashingContext<'a>,
-    hasher: &mut StableHasher,
-    blanket_impls: &[DefId],
-    non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
-) {
-    {
-        let mut blanket_impls: SmallVec<[_; 8]> =
-            blanket_impls.iter().map(|&def_id| hcx.def_path_hash(def_id)).collect();
-
-        if blanket_impls.len() > 1 {
-            blanket_impls.sort_unstable();
-        }
-
-        blanket_impls.hash_stable(hcx, hasher);
-    }
-
-    {
-        let mut keys: SmallVec<[_; 8]> =
-            non_blanket_impls.keys().map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))).collect();
-        keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2));
-        keys.len().hash_stable(hcx, hasher);
-        for (key, ref stable_key) in keys {
-            stable_key.hash_stable(hcx, hasher);
-            let mut impls: SmallVec<[_; 8]> =
-                non_blanket_impls[key].iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect();
-
-            if impls.len() > 1 {
-                impls.sort_unstable();
-            }
-
-            impls.hash_stable(hcx, hasher);
-        }
-    }
-}
index 8e53e4ba948058bdd4351b7a93227ddf27aea74a..3b0640eb98d93fc7035a65983dc4d06fa9dc8c3f 100644 (file)
@@ -90,7 +90,10 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
             ty::ReFree(ref free_region) => {
                 free_region.hash_stable(hcx, hasher);
             }
-            ty::ReVar(..) | ty::RePlaceholder(..) => {
+            ty::RePlaceholder(p) => {
+                p.hash_stable(hcx, hasher);
+            }
+            ty::ReVar(..) => {
                 bug!("StableHasher: unexpected region {:?}", *self)
             }
         }
index c8fb2bf39cc80025f6fab13fbbaa189ceb58b03d..e8e5c4a2669906d31805c081b0d543616505f050 100644 (file)
@@ -1,8 +1,6 @@
 //! ICH - Incremental Compilation Hash
 
-pub use self::hcx::{
-    hash_stable_trait_impls, NodeIdHashingMode, StableHashingContext, StableHashingContextProvider,
-};
+pub use self::hcx::{NodeIdHashingMode, StableHashingContext, StableHashingContextProvider};
 use rustc_span::symbol::{sym, Symbol};
 
 mod hcx;
index bd4e83a42ef515c371bdd9ed0aa702b4d228a537..e271f59da87967fe2c8940425ab2798ea08e2291 100644 (file)
@@ -257,7 +257,8 @@ pub struct ScopeTree {
     /// ```
     ///
     /// With the HIR tree (calls numbered for expository purposes)
-    /// ```
+    ///
+    /// ```text
     ///     Call#0(foo, [Call#1(f), Yield(y), Call#2(bar, Call#3(g))])
     /// ```
     ///
index 3e9c02ee268cab9a9e197198ad41c43a5ca13611..2a36c01d221e1cda6d822aa27eec160ef1074d48 100644 (file)
@@ -2200,6 +2200,12 @@ pub enum Rvalue<'tcx> {
     /// that `Foo` has a destructor. These rvalues can be optimized
     /// away after type-checking and before lowering.
     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
+
+    /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
+    ///
+    /// This is different a normal transmute because dataflow analysis will treat the box
+    /// as initialized but its content as uninitialized.
+    ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -2450,6 +2456,10 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
                     }),
                 }
             }
+
+            ShallowInitBox(ref place, ref ty) => {
+                write!(fmt, "ShallowInitBox({:?}, {:?})", place, ty)
+            }
         }
     }
 }
index b48e8a868efdb1cf01a0b9e9abf5cf93fbbad603..c3c5ebe705effa45fd518ad35dc0e00121124515 100644 (file)
@@ -206,6 +206,7 @@ pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
                     tcx.mk_generator(did, substs, movability)
                 }
             },
+            Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty),
         }
     }
 
@@ -214,7 +215,9 @@ pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
     /// whether its only shallowly initialized (`Rvalue::Box`).
     pub fn initialization_state(&self) -> RvalueInitializationState {
         match *self {
-            Rvalue::NullaryOp(NullOp::Box, _) => RvalueInitializationState::Shallow,
+            Rvalue::NullaryOp(NullOp::Box, _) | Rvalue::ShallowInitBox(_, _) => {
+                RvalueInitializationState::Shallow
+            }
             _ => RvalueInitializationState::Deep,
         }
     }
index b2d4a22194c628a25a4cf004e1a215b6a66b204b..b7201f7acf392dac6567e4d4ba7d6e69298b467c 100644 (file)
@@ -210,6 +210,7 @@ fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
                 });
                 Aggregate(kind, fields.fold_with(folder))
             }
+            ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder), ty.fold_with(folder)),
         }
     }
 
@@ -255,6 +256,10 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
                 }
                 fields.visit_with(visitor)
             }
+            ShallowInitBox(ref op, ty) => {
+                op.visit_with(visitor)?;
+                ty.visit_with(visitor)
+            }
         }
     }
 }
index af7f7796522606a536f190e10ec748270c45b745..fda7ebe1a49c15c2697ae150b964124af43a019e 100644 (file)
@@ -348,7 +348,7 @@ fn super_source_scope_data(
                         ty::InstanceDef::VtableShim(_def_id) |
                         ty::InstanceDef::ReifyShim(_def_id) |
                         ty::InstanceDef::Virtual(_def_id, _) |
-                        ty::InstanceDef::ClosureOnceShim { call_once: _def_id } |
+                        ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
                         ty::InstanceDef::DropGlue(_def_id, None) => {}
 
                         ty::InstanceDef::FnPtrShim(_def_id, ty) |
@@ -753,6 +753,11 @@ fn super_rvalue(&mut self,
                             self.visit_operand(operand, location);
                         }
                     }
+
+                    Rvalue::ShallowInitBox(operand, ty) => {
+                        self.visit_operand(operand, location);
+                        self.visit_ty(ty, TyContext::Location(location));
+                    }
                 }
             }
 
index c13d7720e37540747236a788225c4549d70fb6bc..b4f7a9fa8e9d6584afb69e4201a9ba3fe8281db5 100644 (file)
         desc { "computing the inferred outlives predicates for items in this crate" }
     }
 
-    /// Maps from an impl/trait `DefId to a list of the `DefId`s of its items.
+    /// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items.
     query associated_item_def_ids(key: DefId) -> &'tcx [DefId] {
         desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
     }
index cb60bfa4c5408cff31564af9dee9fc890579567d..ab47c2a7636f95224adc7270b3588f928b3c5ee9 100644 (file)
@@ -1,9 +1,7 @@
-use crate::ich::{self, StableHashingContext};
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::fold::TypeFoldable;
 use crate::ty::{self, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::{DefId, DefIdMap};
 use rustc_span::symbol::Ident;
@@ -50,19 +48,19 @@ pub fn parent(&self, child: DefId) -> DefId {
 
 /// Children of a given impl, grouped into blanket/non-blanket varieties as is
 /// done in `TraitDef`.
-#[derive(Default, TyEncodable, TyDecodable, Debug)]
+#[derive(Default, TyEncodable, TyDecodable, Debug, HashStable)]
 pub struct Children {
     // Impls of a trait (or specializations of a given impl). To allow for
     // quicker lookup, the impls are indexed by a simplified version of their
     // `Self` type: impls with a simplifiable `Self` are stored in
-    // `nonblanket_impls` keyed by it, while all other impls are stored in
+    // `non_blanket_impls` keyed by it, while all other impls are stored in
     // `blanket_impls`.
     //
     // A similar division is used within `TraitDef`, but the lists there collect
     // together *all* the impls for a trait, and are populated prior to building
     // the specialization graph.
     /// Impls of the trait.
-    pub nonblanket_impls: FxHashMap<SimplifiedType, Vec<DefId>>,
+    pub non_blanket_impls: FxIndexMap<SimplifiedType, Vec<DefId>>,
 
     /// Blanket impls associated with the trait.
     pub blanket_impls: Vec<DefId>,
@@ -235,11 +233,3 @@ pub fn ancestors(
         })
     }
 }
-
-impl<'a> HashStable<StableHashingContext<'a>> for Children {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let Children { ref nonblanket_impls, ref blanket_impls } = *self;
-
-        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls);
-    }
-}
index 261a19f862e02958b226f4e386f04c6ce17793b6..9b8247fd0283e3d62c554e39bf918152357779b4 100644 (file)
@@ -77,7 +77,7 @@ pub enum InstanceDef<'tcx> {
     /// `<[FnMut closure] as FnOnce>::call_once`.
     ///
     /// The `DefId` is the ID of the `call_once` method in `FnOnce`.
-    ClosureOnceShim { call_once: DefId },
+    ClosureOnceShim { call_once: DefId, track_caller: bool },
 
     /// `core::ptr::drop_in_place::<T>`.
     ///
@@ -146,7 +146,7 @@ pub fn def_id(self) -> DefId {
             | InstanceDef::FnPtrShim(def_id, _)
             | InstanceDef::Virtual(def_id, _)
             | InstanceDef::Intrinsic(def_id)
-            | InstanceDef::ClosureOnceShim { call_once: def_id }
+            | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
             | InstanceDef::DropGlue(def_id, _)
             | InstanceDef::CloneShim(def_id, _) => def_id,
         }
@@ -161,7 +161,7 @@ pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
             | InstanceDef::FnPtrShim(def_id, _)
             | InstanceDef::Virtual(def_id, _)
             | InstanceDef::Intrinsic(def_id)
-            | InstanceDef::ClosureOnceShim { call_once: def_id }
+            | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
             | InstanceDef::DropGlue(def_id, _)
             | InstanceDef::CloneShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
         }
@@ -231,6 +231,7 @@ pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
             | InstanceDef::Virtual(def_id, _) => {
                 tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
             }
+            InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
             _ => false,
         }
     }
@@ -381,6 +382,8 @@ pub fn resolve_for_fn_ptr(
         substs: SubstsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
         debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
+        // Use either `resolve_closure` or `resolve_for_vtable`
+        assert!(!tcx.is_closure(def_id), "Called `resolve_for_fn_ptr` on closure: {:?}", def_id);
         Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
             match resolved.def {
                 InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
@@ -442,10 +445,20 @@ pub fn resolve_for_vtable(
                                 })
                             )
                         {
-                            debug!(
-                                " => vtable fn pointer created for function with #[track_caller]"
-                            );
-                            resolved.def = InstanceDef::ReifyShim(def.did);
+                            if tcx.is_closure(def.did) {
+                                debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
+                                       def.did, def_id, substs);
+
+                                // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
+                                // - unlike functions, invoking a closure always goes through a
+                                // trait.
+                                resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs };
+                            } else {
+                                debug!(
+                                    " => vtable fn pointer created for function with #[track_caller]: {:?}", def.did
+                                );
+                                resolved.def = InstanceDef::ReifyShim(def.did);
+                            }
                         }
                     }
                     InstanceDef::Virtual(def_id, _) => {
@@ -493,7 +506,9 @@ pub fn fn_once_adapter_instance(
             .find(|it| it.kind == ty::AssocKind::Fn)
             .unwrap()
             .def_id;
-        let def = ty::InstanceDef::ClosureOnceShim { call_once };
+        let track_caller =
+            tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER);
+        let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller };
 
         let self_ty = tcx.mk_closure(closure_did, substs);
 
index 777c6035be831c503043aacd9e89ca503952979c..b3ae76d987167fe84fa32c13f7ed621f42c96aac 100644 (file)
@@ -769,12 +769,6 @@ pub trait ToPolyTraitRef<'tcx> {
     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
 }
 
-impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
-    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
-        ty::Binder::dummy(*self)
-    }
-}
-
 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
         self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
@@ -792,23 +786,6 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
     }
 }
 
-impl ToPredicate<'tcx> for PredicateKind<'tcx> {
-    #[inline(always)]
-    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
-        tcx.mk_predicate(Binder::dummy(self))
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
-    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
-        PredicateKind::Trait(ty::TraitPredicate {
-            trait_ref: self.value,
-            constness: self.constness,
-        })
-        .to_predicate(tcx)
-    }
-}
-
 impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         self.value
@@ -2090,3 +2067,16 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(&self.name, fmt)
     }
 }
+
+#[derive(Debug, Default, Copy, Clone)]
+pub struct FoundRelationships {
+    /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
+    /// obligation, where:
+    ///
+    ///  * `Foo` is not `Sized`
+    ///  * `(): Foo` may be satisfied
+    pub self_in_trait: bool,
+    /// This is true if we identified that this Ty (`?T`) is found in a `<_ as
+    /// _>::AssocType = ?T`
+    pub output: bool,
+}
index db4a1d94d1a7c28bf8f180763fe0182ab39fda34..d99534c200a5a557c8e1dcff2d1241c8ca00071a 100644 (file)
@@ -59,6 +59,7 @@ macro_rules! scoped_cx {
     static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = const { Cell::new(false) };
     static NO_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
     static NO_QUERIES: Cell<bool> = const { Cell::new(false) };
+    static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
 }
 
 /// Avoids running any queries during any prints that occur
@@ -112,6 +113,16 @@ pub fn with_no_trimmed_paths<F: FnOnce() -> R, R>(f: F) -> R {
     })
 }
 
+/// Prevent selection of visible paths. `Display` impl of DefId will prefer visible (public) reexports of types as paths.
+pub fn with_no_visible_paths<F: FnOnce() -> R, R>(f: F) -> R {
+    NO_VISIBLE_PATH.with(|flag| {
+        let old = flag.replace(true);
+        let result = f();
+        flag.set(old);
+        result
+    })
+}
+
 /// The "region highlights" are used to control region printing during
 /// specific error messages. When a "region highlight" is enabled, it
 /// gives an alternate way to print specific regions. For now, we
@@ -268,6 +279,10 @@ fn generic_delimiters(
     /// from at least one local module, and returns `true`. If the crate defining `def_id` is
     /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
     fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> {
+        if NO_VISIBLE_PATH.with(|flag| flag.get()) {
+            return Ok((self, false));
+        }
+
         let mut callers = Vec::new();
         self.try_print_visible_def_path_recur(def_id, &mut callers)
     }
index 9d1be212f5b8c49771a62de47cc48263bc8032f7..2c786538014ff20421324e5927de8a613caaf4e0 100644 (file)
@@ -639,6 +639,15 @@ fn check_const_value_eq<R: TypeRelation<'tcx>>(
             get_slice_bytes(&tcx, a_val) == get_slice_bytes(&tcx, b_val)
         }
 
+        (ConstValue::ByRef { alloc: alloc_a, .. }, ConstValue::ByRef { alloc: alloc_b, .. })
+            if a.ty.is_ref() || b.ty.is_ref() =>
+        {
+            if a.ty.is_ref() && b.ty.is_ref() {
+                alloc_a == alloc_b
+            } else {
+                false
+            }
+        }
         (ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => {
             let a_destructured = tcx.destructure_const(relation.param_env().and(a));
             let b_destructured = tcx.destructure_const(relation.param_env().and(b));
index 89ad99d9f0794f6d9f7805a4d7c96bd86dbdf7c5..8f343ba9fec22064b964c13198292c795f310a77 100644 (file)
@@ -638,8 +638,8 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
                 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
             }
             ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)),
-            ty::InstanceDef::ClosureOnceShim { call_once } => {
-                Some(ty::InstanceDef::ClosureOnceShim { call_once })
+            ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => {
+                Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller })
             }
             ty::InstanceDef::DropGlue(def_id, ty) => {
                 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?))
@@ -824,8 +824,8 @@ fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
                 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
                 FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
                 Virtual(did, i) => Virtual(did.fold_with(folder), i),
-                ClosureOnceShim { call_once } => {
-                    ClosureOnceShim { call_once: call_once.fold_with(folder) }
+                ClosureOnceShim { call_once, track_caller } => {
+                    ClosureOnceShim { call_once: call_once.fold_with(folder), track_caller }
                 }
                 DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)),
                 CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.fold_with(folder)),
@@ -849,7 +849,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
                 did.visit_with(visitor)?;
                 ty.visit_with(visitor)
             }
-            ClosureOnceShim { call_once } => call_once.visit_with(visitor),
+            ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor),
         }
     }
 }
index 0fbaf81c21e40e7c0a22e4dafbab9f25193d6ca8..d3094b3e6ff4d74ccb3ea809de72d01ebcd1bcf2 100644 (file)
@@ -844,8 +844,11 @@ pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> {
 
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
     /// are the parameters defined on trait.
-    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
-        TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) }
+    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
+        ty::Binder::dummy(TraitRef {
+            def_id,
+            substs: InternalSubsts::identity_for_item(tcx, def_id),
+        })
     }
 
     #[inline]
@@ -1672,6 +1675,14 @@ pub fn is_ty_var(&self) -> bool {
         matches!(self.kind(), Infer(TyVar(_)))
     }
 
+    #[inline]
+    pub fn ty_vid(&self) -> Option<ty::TyVid> {
+        match self.kind() {
+            &Infer(TyVar(vid)) => Some(vid),
+            _ => None,
+        }
+    }
+
     #[inline]
     pub fn is_ty_infer(&self) -> bool {
         matches!(self.kind(), Infer(_))
index ae86f51e6ac3fd4bdc045e1f6df4d7e26216868f..25a310b12db58ea34d512e12d7037544272f6f33 100644 (file)
@@ -1,4 +1,3 @@
-use crate::ich::{self, StableHashingContext};
 use crate::traits::specialization_graph;
 use crate::ty::fast_reject;
 use crate::ty::fold::TypeFoldable;
@@ -7,8 +6,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::DefPathHash;
 
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorReported;
 use rustc_macros::HashStable;
 
@@ -66,11 +64,11 @@ pub enum TraitSpecializationKind {
     AlwaysApplicable,
 }
 
-#[derive(Default, Debug)]
+#[derive(Default, Debug, HashStable)]
 pub struct TraitImpls {
     blanket_impls: Vec<DefId>,
     /// Impls indexed by their simplified self type, for fast lookup.
-    non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
+    non_blanket_impls: FxIndexMap<fast_reject::SimplifiedType, Vec<DefId>>,
 }
 
 impl TraitImpls {
@@ -249,11 +247,3 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
 
     impls
 }
-
-impl<'a> HashStable<StableHashingContext<'a>> for TraitImpls {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self;
-
-        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls);
-    }
-}
index e9fbc1b186d19fb361a4f5789c8ce2edcb2c9f9c..998b80a36c2f7eb73ecb7e920eeb6969cfa89450 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_mir_build"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 4b40faaf1956db04f344bf947ddcca0add3563e4..1464ea58ad02c6581fc0c298d015745e04340534 100644 (file)
@@ -5,6 +5,7 @@
 use crate::build::expr::as_place::PlaceBase;
 use crate::build::expr::category::{Category, RvalueFunc};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use rustc_hir::lang_items::LangItem;
 use rustc_middle::middle::region;
 use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::Place;
@@ -88,6 +89,56 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             ExprKind::Box { value } => {
                 let value = &this.thir[value];
+                let tcx = this.tcx;
+
+                // `exchange_malloc` is unsafe but box is safe, so need a new scope.
+                let synth_scope = this.new_source_scope(
+                    expr_span,
+                    LintLevel::Inherited,
+                    Some(Safety::BuiltinUnsafe),
+                );
+                let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
+
+                let size = this.temp(tcx.types.usize, expr_span);
+                this.cfg.push_assign(
+                    block,
+                    synth_info,
+                    size,
+                    Rvalue::NullaryOp(NullOp::SizeOf, value.ty),
+                );
+
+                let align = this.temp(tcx.types.usize, expr_span);
+                this.cfg.push_assign(
+                    block,
+                    synth_info,
+                    align,
+                    Rvalue::NullaryOp(NullOp::AlignOf, value.ty),
+                );
+
+                // malloc some memory of suitable size and align:
+                let exchange_malloc = Operand::function_handle(
+                    tcx,
+                    tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)),
+                    ty::List::empty(),
+                    expr_span,
+                );
+                let storage = this.temp(tcx.mk_mut_ptr(tcx.types.u8), expr_span);
+                let success = this.cfg.start_new_block();
+                this.cfg.terminate(
+                    block,
+                    synth_info,
+                    TerminatorKind::Call {
+                        func: exchange_malloc,
+                        args: vec![Operand::Move(size), Operand::Move(align)],
+                        destination: Some((Place::from(storage), success)),
+                        cleanup: None,
+                        from_hir_call: false,
+                        fn_span: expr_span,
+                    },
+                );
+                this.diverge_from(block);
+                block = success;
+
                 // The `Box<T>` temporary created here is not a part of the HIR,
                 // and therefore is not considered during generator auto-trait
                 // determination. See the comment about `box` at `yield_in_scope`.
@@ -101,8 +152,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     this.schedule_drop_storage_and_value(expr_span, scope, result);
                 }
 
-                // malloc some memory of suitable type (thus far, uninitialized):
-                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
+                // Transmute `*mut u8` to the box (thus far, uninitialized):
+                let box_ = Rvalue::ShallowInitBox(Operand::Move(Place::from(storage)), value.ty);
                 this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
                 // initialize the box contents:
index 0ee740a6463593de96e159b1ffd434919aaa75d8..4108ad50470b711f217ecdcfe9d07b24672e10cc 100644 (file)
@@ -44,15 +44,18 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
     let body_owner_kind = tcx.hir().body_owner_kind(id);
     let typeck_results = tcx.typeck_opt_const_arg(def);
 
-    // Ensure unsafeck is ran before we steal the THIR.
+    // Ensure unsafeck and abstract const building is ran before we steal the THIR.
+    // We can't use `ensure()` for `thir_abstract_const` as it doesn't compute the query
+    // if inputs are green. This can cause ICEs when calling `thir_abstract_const` after
+    // THIR has been stolen if we haven't computed this query yet.
     match def {
         ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
             tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did));
-            tcx.ensure().thir_abstract_const_of_const_arg((did, const_param_did));
+            drop(tcx.thir_abstract_const_of_const_arg((did, const_param_did)));
         }
         ty::WithOptConstParam { did, const_param_did: None } => {
             tcx.ensure().thir_check_unsafety(did);
-            tcx.ensure().thir_abstract_const(did);
+            drop(tcx.thir_abstract_const(did));
         }
     }
 
index bbb5de34d1860a84011421cfebb78e1130a76488..847b89f0464f6fa474ea962ed70448b24711a903 100644 (file)
@@ -322,16 +322,18 @@ fn recur(
                     && !self.saw_const_match_lint.get()
                 {
                     self.saw_const_match_lint.set(true);
-                    let msg = format!(
-                        "to use a constant of type `{}` in a pattern, \
-                        `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
-                        cv.ty, cv.ty,
-                    );
                     tcx.struct_span_lint_hir(
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                         id,
                         span,
-                        |lint| lint.build(&msg).emit(),
+                        |lint| {
+                            let msg = format!(
+                                "to use a constant of type `{}` in a pattern, \
+                                 `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
+                                cv.ty, cv.ty,
+                            );
+                            lint.build(&msg).emit()
+                        },
                     );
                 }
                 // Since we are behind a reference, we can just bubble the error up so we get a
index 3cd4892402e4c36ef493d2a6ff1ffc152bfaba59..ffd7e3cd06bd266d1e797fb981811cfe1459cbe7 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_mir_dataflow"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 81d84f80ad4c19a2cf083639abeb7bee435afe49..158ba1b942528072c7416f70fe9cb434590e83a6 100644 (file)
@@ -169,6 +169,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
             }
 
             mir::Rvalue::Cast(..)
+            | mir::Rvalue::ShallowInitBox(..)
             | mir::Rvalue::Use(..)
             | mir::Rvalue::ThreadLocalRef(..)
             | mir::Rvalue::Repeat(..)
index 407ba739463013ddb2346298efcc0774134141d9..e404b49ecb93173f33ca1062399967f3f6a6075b 100644 (file)
@@ -327,6 +327,7 @@ fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
             Rvalue::Use(ref operand)
             | Rvalue::Repeat(ref operand, _)
             | Rvalue::Cast(_, ref operand, _)
+            | Rvalue::ShallowInitBox(ref operand, _)
             | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
             Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs))
             | Rvalue::CheckedBinaryOp(ref _binop, box (ref lhs, ref rhs)) => {
index 5e1a587b0ecead71635b3a70a71527e93106a133..bde4e215a2a61629d3ea8fef2261490fe8926cdf 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_mir_transform"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 71b3a555587f710c748f332f29c5d99611087f0a..17790ec91c8a3fd17d19132ad21aba33e9255712 100644 (file)
@@ -723,6 +723,7 @@ fn const_prop(
             | Rvalue::Repeat(..)
             | Rvalue::Len(..)
             | Rvalue::Cast(..)
+            | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
             | Rvalue::NullaryOp(..) => {}
         }
index cc93fd482b5d49d4400e4d47b3a517dd1b346cdf..f5e8b65656a3ebe981bf8242e9f85caa97cf0373 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "coverage_test_macros"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 proc-macro = true
index dd95f0014230953d1f96c9139c2c4daed42606e3..790d9243fbaec874db7488ff817c615d5068cb1e 100644 (file)
@@ -967,6 +967,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
             }
 
             Rvalue::Cast(..)
+            | Rvalue::ShallowInitBox(..)
             | Rvalue::Use(..)
             | Rvalue::Repeat(..)
             | Rvalue::Len(..)
index 1945e551485d8fcf939fd8263e3e9f9715916b69..3002e7041b0247dacd18e868907799cbe39b37fa 100644 (file)
@@ -204,6 +204,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
                         | Rvalue::AddressOf(_, _)
                         | Rvalue::Cast(_, Operand::Constant(_), _)
                         | Rvalue::NullaryOp(_, _)
+                        | Rvalue::ShallowInitBox(_, _)
                         | Rvalue::UnaryOp(_, Operand::Constant(_)) => return true,
 
                         // These rvalues make things ambiguous
@@ -301,6 +302,7 @@ fn find_determining_place<'tcx>(
                     | Rvalue::ThreadLocalRef(_)
                     | Rvalue::AddressOf(_, _)
                     | Rvalue::NullaryOp(_, _)
+                    | Rvalue::ShallowInitBox(_, _)
                     | Rvalue::UnaryOp(_, Operand::Constant(_))
                     | Rvalue::Cast(_, Operand::Constant(_), _)
                     => return None,
index 4d350fc87cb3aebbb3db0c9654af20e3526fbd33..f2ea5fedc625c68596af7464c4e7dc9598a1cfda 100644 (file)
@@ -53,7 +53,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
         ty::InstanceDef::ReifyShim(def_id) => {
             build_call_shim(tcx, instance, None, CallKind::Direct(def_id))
         }
-        ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
+        ty::InstanceDef::ClosureOnceShim { call_once: _, track_caller: _ } => {
             let fn_mut = tcx.require_lang_item(LangItem::FnMut, None);
             let call_mut = tcx
                 .associated_items(fn_mut)
index 350ae08877718e38fc0c561c676d306048fa148e..f812afe6b62ba9cd88c6e660c056f94abc9065c1 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_monomorphize"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 1ca1a92252ea48c6f2189408f36e0cf0c2f4c6e2..1decaaa955f023075367e523b4e801eec49a2cb1 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_parse"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index aa6b424ce2b57ec167c85c7086471cc3165d62ec..cef5b3a226bff81a65f1fa69da5bdfc227e06a77 100644 (file)
@@ -3,7 +3,7 @@
 use std::iter::once;
 use std::ops::Range;
 
-use rustc_errors::{Applicability, Handler};
+use rustc_errors::{pluralize, Applicability, Handler};
 use rustc_lexer::unescape::{EscapeError, Mode};
 use rustc_span::{BytePos, Span};
 
@@ -49,24 +49,57 @@ pub(crate) fn emit_unescape_error(
                 .emit();
         }
         EscapeError::MoreThanOneChar => {
-            let (prefix, msg) = if mode.is_bytes() {
-                ("b", "if you meant to write a byte string literal, use double quotes")
-            } else {
-                ("", "if you meant to write a `str` literal, use double quotes")
-            };
+            use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
 
-            handler
-                .struct_span_err(
-                    span_with_quotes,
-                    "character literal may only contain one codepoint",
-                )
-                .span_suggestion(
+            let mut has_help = false;
+            let mut handler = handler.struct_span_err(
+                span_with_quotes,
+                "character literal may only contain one codepoint",
+            );
+
+            if lit.chars().skip(1).all(|c| is_combining_mark(c)) {
+                let escaped_marks =
+                    lit.chars().skip(1).map(|c| c.escape_default().to_string()).collect::<Vec<_>>();
+                handler.span_note(
+                    span,
+                    &format!(
+                        "this `{}` is followed by the combining mark{} `{}`",
+                        lit.chars().next().unwrap(),
+                        pluralize!(escaped_marks.len()),
+                        escaped_marks.join(""),
+                    ),
+                );
+                let normalized = lit.nfc().to_string();
+                if normalized.chars().count() == 1 {
+                    has_help = true;
+                    handler.span_suggestion(
+                        span,
+                        &format!(
+                            "consider using the normalized form `{}` of this character",
+                            normalized.chars().next().unwrap().escape_default()
+                        ),
+                        normalized,
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
+
+            if !has_help {
+                let (prefix, msg) = if mode.is_bytes() {
+                    ("b", "if you meant to write a byte string literal, use double quotes")
+                } else {
+                    ("", "if you meant to write a `str` literal, use double quotes")
+                };
+
+                handler.span_suggestion(
                     span_with_quotes,
                     msg,
                     format!("{}\"{}\"", prefix, lit),
                     Applicability::MachineApplicable,
-                )
-                .emit();
+                );
+            }
+
+            handler.emit();
         }
         EscapeError::EscapeOnlyChar => {
             let (c, char_span) = last_char();
index af41a99ada4dd57997756c1f318b3a38c79741c5..a40f47f895bbea170b52ab030ce1b0fbf333f075 100644 (file)
@@ -6,6 +6,9 @@
 #![feature(box_patterns)]
 #![recursion_limit = "256"]
 
+#[macro_use]
+extern crate tracing;
+
 use rustc_ast as ast;
 use rustc_ast::token::{self, Nonterminal, Token, TokenKind};
 use rustc_ast::tokenstream::{self, AttributesData, CanSynthesizeMissingTokens, LazyTokenStream};
index 708df5e46d4e22ef94dca8c3bdd49f61a8f53800..8095f386fa3615144125bca5a0ebd9897a81789b 100644 (file)
@@ -277,7 +277,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
                 self.struct_span_err(sp, &msg)
                     .span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl)
                     .emit();
-                return Ok(false);
+                return Ok(true);
             } else if self.look_ahead(0, |t| {
                 t == &token::CloseDelim(token::Brace)
                     || (
@@ -295,7 +295,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
                     .span_label(self.token.span, "unexpected token")
                     .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl)
                     .emit();
-                return Ok(false);
+                return Ok(true);
             }
         }
 
index c62ea66b693e3153940dd1dec6cb6dba7525a219..c5417ea23f2190ab466b5a06a2ab90735f937bb3 100644 (file)
@@ -1084,6 +1084,7 @@ fn parse_fn_call_expr(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
 
     /// If we encounter a parser state that looks like the user has written a `struct` literal with
     /// parentheses instead of braces, recover the parser state and provide suggestions.
+    #[instrument(skip(self, seq, snapshot), level = "trace")]
     fn maybe_recover_struct_lit_bad_delims(
         &mut self,
         lo: Span,
@@ -1567,6 +1568,20 @@ pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
 
     pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
         self.parse_opt_lit().ok_or_else(|| {
+            if let token::Interpolated(inner) = &self.token.kind {
+                let expr = match inner.as_ref() {
+                    token::NtExpr(expr) => Some(expr),
+                    token::NtLiteral(expr) => Some(expr),
+                    _ => None,
+                };
+                if let Some(expr) = expr {
+                    if matches!(expr.kind, ExprKind::Err) {
+                        self.diagnostic()
+                            .delay_span_bug(self.token.span, &"invalid interpolated expression");
+                        return self.diagnostic().struct_dummy();
+                    }
+                }
+            }
             let msg = format!("unexpected token: {}", super::token_descr(&self.token));
             self.struct_span_err(self.token.span, &msg)
         })
index 0e2222bf84093913d3bfc926621130452c7ac6fd..624390a406ff2bbcfbbbf3b298f6d1e124dec01c 100644 (file)
@@ -1547,6 +1547,20 @@ fn parse_item_macro_rules(&mut self, vis: &Visibility) -> PResult<'a, ItemInfo>
         self.expect(&token::Not)?; // `!`
 
         let ident = self.parse_ident()?;
+
+        if self.eat(&token::Not) {
+            // Handle macro_rules! foo!
+            let span = self.prev_token.span;
+            self.struct_span_err(span, "macro names aren't followed by a `!`")
+                .span_suggestion(
+                    span,
+                    "remove the `!`",
+                    "".to_owned(),
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+        }
+
         let body = self.parse_mac_args()?;
         self.eat_semi_for_macro_if_needed(&body);
         self.complain_if_pub_macro(vis, true);
index 67695dc285092a555cc391e41bbe4e9e6eaedddc..2aa20d02c8830cd38437848b9de82b00040e1bf5 100644 (file)
@@ -4,7 +4,7 @@
 
 use rustc_ast::tokenstream::{DelimSpan, TokenTree};
 use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
 use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
 use rustc_session::parse::ParseSess;
@@ -91,69 +91,11 @@ pub fn check_builtin_attribute(
     // Some special attributes like `cfg` must be checked
     // before the generic check, so we skip them here.
     let should_skip = |name| name == sym::cfg;
-    // Some of previously accepted forms were used in practice,
-    // report them as warnings for now.
-    let should_warn = |name| {
-        name == sym::doc
-            || name == sym::ignore
-            || name == sym::inline
-            || name == sym::link
-            || name == sym::test
-            || name == sym::bench
-    };
 
     match parse_meta(sess, attr) {
         Ok(meta) => {
             if !should_skip(name) && !is_attr_template_compatible(&template, &meta.kind) {
-                let error_msg = format!("malformed `{}` attribute input", name);
-                let mut msg = "attribute must be of the form ".to_owned();
-                let mut suggestions = vec![];
-                let mut first = true;
-                if template.word {
-                    first = false;
-                    let code = format!("#[{}]", name);
-                    msg.push_str(&format!("`{}`", &code));
-                    suggestions.push(code);
-                }
-                if let Some(descr) = template.list {
-                    if !first {
-                        msg.push_str(" or ");
-                    }
-                    first = false;
-                    let code = format!("#[{}({})]", name, descr);
-                    msg.push_str(&format!("`{}`", &code));
-                    suggestions.push(code);
-                }
-                if let Some(descr) = template.name_value_str {
-                    if !first {
-                        msg.push_str(" or ");
-                    }
-                    let code = format!("#[{} = \"{}\"]", name, descr);
-                    msg.push_str(&format!("`{}`", &code));
-                    suggestions.push(code);
-                }
-                if should_warn(name) {
-                    sess.buffer_lint(
-                        &ILL_FORMED_ATTRIBUTE_INPUT,
-                        meta.span,
-                        ast::CRATE_NODE_ID,
-                        &msg,
-                    );
-                } else {
-                    sess.span_diagnostic
-                        .struct_span_err(meta.span, &error_msg)
-                        .span_suggestions(
-                            meta.span,
-                            if suggestions.len() == 1 {
-                                "must be of the form"
-                            } else {
-                                "the following are the possible correct uses"
-                            },
-                            suggestions.into_iter(),
-                            Applicability::HasPlaceholders,
-                        )
-                        .emit();
-                }
+                emit_malformed_attribute(sess, attr, name, template);
             }
         }
         Err(mut err) => {
@@ -161,3 +103,74 @@ pub fn check_builtin_attribute(
         }
     }
 }
+
+fn emit_malformed_attribute(
+    sess: &ParseSess,
+    attr: &Attribute,
+    name: Symbol,
+    template: AttributeTemplate,
+) {
+    // Some of previously accepted forms were used in practice,
+    // report them as warnings for now.
+    let should_warn = |name| {
+        matches!(name, sym::doc | sym::ignore | sym::inline | sym::link | sym::test | sym::bench)
+    };
+
+    let error_msg = format!("malformed `{}` attribute input", name);
+    let mut msg = "attribute must be of the form ".to_owned();
+    let mut suggestions = vec![];
+    let mut first = true;
+    let inner = if attr.style == ast::AttrStyle::Inner { "!" } else { "" };
+    if template.word {
+        first = false;
+        let code = format!("#{}[{}]", inner, name);
+        msg.push_str(&format!("`{}`", &code));
+        suggestions.push(code);
+    }
+    if let Some(descr) = template.list {
+        if !first {
+            msg.push_str(" or ");
+        }
+        first = false;
+        let code = format!("#{}[{}({})]", inner, name, descr);
+        msg.push_str(&format!("`{}`", &code));
+        suggestions.push(code);
+    }
+    if let Some(descr) = template.name_value_str {
+        if !first {
+            msg.push_str(" or ");
+        }
+        let code = format!("#{}[{} = \"{}\"]", inner, name, descr);
+        msg.push_str(&format!("`{}`", &code));
+        suggestions.push(code);
+    }
+    if should_warn(name) {
+        sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, attr.span, ast::CRATE_NODE_ID, &msg);
+    } else {
+        sess.span_diagnostic
+            .struct_span_err(attr.span, &error_msg)
+            .span_suggestions(
+                attr.span,
+                if suggestions.len() == 1 {
+                    "must be of the form"
+                } else {
+                    "the following are the possible correct uses"
+                },
+                suggestions.into_iter(),
+                Applicability::HasPlaceholders,
+            )
+            .emit();
+    }
+}
+
+pub fn emit_fatal_malformed_builtin_attribute(
+    sess: &ParseSess,
+    attr: &Attribute,
+    name: Symbol,
+) -> ! {
+    let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").2;
+    emit_malformed_attribute(sess, attr, name, template);
+    // This is fatal, otherwise it will likely cause a cascade of other errors
+    // (and an error here is expected to be very rare).
+    FatalError.raise()
+}
index 7b77560717e139509bdc523dd2a8a686ecbc02c5..aa1714e820f4862a035ce10a11946245267d060c 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_parse_format"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 rustc_span = { path = "../rustc_span" }
index bf1e52cd9a8ad4a18eb567de9418cba1e295e027..39e578bce7ef67eecb9287da9fc56f77770bd800 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_passes"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 tracing = "0.1"
index fd438bdc9005ac5557c389bfa58ec7c9a5c860fe..3e59fc4f551594ec22b7725e5efc9b6c628b8ae1 100644 (file)
@@ -104,6 +104,7 @@ fn check_attributes(
                 sym::default_method_body_is_const => {
                     self.check_default_method_body_is_const(attr, span, target)
                 }
+                sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
                 sym::rustc_const_unstable
                 | sym::rustc_const_stable
                 | sym::unstable
@@ -1014,6 +1015,21 @@ fn check_doc_attrs(
         is_valid
     }
 
+    /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid.
+    fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
+        match target {
+            Target::Struct | Target::Enum | Target::Union | Target::Trait => true,
+            _ => {
+                self.tcx
+                    .sess
+                    .struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait")
+                        .span_label(*span, "is not a struct, enum, or trait")
+                        .emit();
+                false
+            }
+        }
+    }
+
     /// Checks if `#[cold]` is applied to a non-function. Returns `true` if valid.
     fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
         match target {
index eff1096c855971b73af65b5dbea2eadde40bd74c..0e60ca9f900107a011ecfaa229c220b298de45b1 100644 (file)
@@ -163,14 +163,14 @@ fn visit_id(&mut self, hir_id: HirId) {
         self.hir_ids_seen.insert(hir_id.local_id);
     }
 
-    fn visit_impl_item_ref(&mut self, _: &'hir hir::ImplItemRef<'hir>) {
+    fn visit_impl_item_ref(&mut self, _: &'hir hir::ImplItemRef) {
         // Explicitly do nothing here. ImplItemRefs contain hir::Visibility
         // values that actually belong to an ImplItem instead of the ItemKind::Impl
         // we are currently in. So for those it's correct that they have a
         // different owner.
     }
 
-    fn visit_foreign_item_ref(&mut self, _: &'hir hir::ForeignItemRef<'hir>) {
+    fn visit_foreign_item_ref(&mut self, _: &'hir hir::ForeignItemRef) {
         // Explicitly do nothing here. ForeignItemRefs contain hir::Visibility
         // values that actually belong to an ForeignItem instead of the ItemKind::ForeignMod
         // we are currently in. So for those it's correct that they have a
index c8eaca0703cb5b176968e4db1a6badb5634746f3..4e666e7e93d530faff9ff5e4797065376e05c45a 100644 (file)
@@ -2,7 +2,7 @@
 name = "rustc_plugin_impl"
 version = "0.0.0"
 build = false
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 6ac2915c3452688b40b1d98ac57f040b10a8f486..d952e288a6477c46864dde961e2999dca16bf557 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_privacy"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 rustc_middle = { path = "../rustc_middle" }
index 391e43054239d2d9929acd6c89ab01eb9989a357..e14f758ddae79662db51d039b80d2cff40985112 100644 (file)
@@ -743,7 +743,9 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
             }
             hir::ItemKind::Impl(ref impl_) => {
                 for impl_item_ref in impl_.items {
-                    if impl_.of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
+                    if impl_.of_trait.is_some()
+                        || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
+                    {
                         self.update(impl_item_ref.id.def_id, item_level);
                     }
                 }
@@ -768,7 +770,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
             }
             hir::ItemKind::ForeignMod { items, .. } => {
                 for foreign_item in items {
-                    if foreign_item.vis.node.is_pub() {
+                    if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public {
                         self.update(foreign_item.id.def_id, item_level);
                     }
                 }
@@ -1678,7 +1680,10 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item_ref in impl_.items {
-                        if self.item_is_public(impl_item_ref.id.def_id, &impl_item_ref.vis) {
+                        if self.access_levels.is_reachable(impl_item_ref.id.def_id)
+                            || self.tcx.visibility(impl_item_ref.id.def_id)
+                                == ty::Visibility::Public
+                        {
                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
                                 AssocItemKind::Const => {
index 7c8dbe34240e215dd639aab75e28d50b6a3b91c5..89df3d4674b6b363cc471fe89329292966f3329d 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_query_impl"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 90a6ba474b405acd1b2c8fcbeedf11b4cc28bfb7..bb686b5ef3f3a9c6f95d3e5bf98b50cd2569b9d7 100644 (file)
@@ -321,10 +321,13 @@ mod make_query {
             pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame {
                 let kind = dep_graph::DepKind::$name;
                 let name = stringify!($name);
-                let description = ty::print::with_forced_impl_filename_line(
+                // Disable visible paths printing for performance reasons.
+                // Showing visible path instead of any path is not that important in production.
+                let description = ty::print::with_no_visible_paths(
+                    || ty::print::with_forced_impl_filename_line(
                     // Force filename-line mode to avoid invoking `type_of` query.
                     || queries::$name::describe(tcx, key)
-                );
+                ));
                 let description = if tcx.sess.verbose() {
                     format!("{} [{}]", description, name)
                 } else {
index 47fb78be6407967736fd3c64ff750d7bc7595951..11c18a497e5e6393d347493b2e82c327eef7cb3a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_query_system"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 1581b0562752e9535a9ba2bf76454c70d68fd2ab..f1d3315d6e66a95d7eace650757eb4cc063a1823 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_resolve"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 test = false
index 55f2b04c4f1c1f6f258238e5bb8d14829eb5e41b..0cf9d7af58933e3f112c3f2512fe78240f8d3e19 100644 (file)
@@ -9,11 +9,9 @@
 use crate::imports::{Import, ImportKind};
 use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
 use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
-use crate::{CrateLint, Determinacy, PathResult, ResolutionError, VisResolutionError};
-use crate::{
-    ExternPreludeEntry, ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas,
-};
-use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
+use crate::{CrateLint, Determinacy, ExternPreludeEntry, Module, ModuleKind, ModuleOrUniformRoot};
+use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
+use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
 
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
 use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
@@ -95,100 +93,93 @@ impl<'a> Resolver<'a> {
     }
 
     /// Walks up the tree of definitions starting at `def_id`,
-    /// stopping at the first `DefKind::Mod` encountered
-    fn nearest_parent_mod(&mut self, def_id: DefId) -> Module<'a> {
-        let def_key = self.cstore().def_key(def_id);
-
-        let mut parent_id = DefId {
-            krate: def_id.krate,
-            index: def_key.parent.expect("failed to get parent for module"),
-        };
-        // The immediate parent may not be a module
-        // (e.g. `const _: () =  { #[path = "foo.rs"] mod foo; };`)
-        // Walk up the tree until we hit a module or the crate root.
-        while parent_id.index != CRATE_DEF_INDEX
-            && self.cstore().def_kind(parent_id) != DefKind::Mod
-        {
-            let parent_def_key = self.cstore().def_key(parent_id);
-            parent_id.index = parent_def_key.parent.expect("failed to get parent for module");
+    /// stopping at the first encountered module.
+    /// Parent block modules for arbitrary def-ids are not recorded for the local crate,
+    /// and are not preserved in metadata for foreign crates, so block modules are never
+    /// returned by this function.
+    ///
+    /// For the local crate ignoring block modules may be incorrect, so use this method with care.
+    ///
+    /// For foreign crates block modules can be ignored without introducing observable differences,
+    /// moreover they has to be ignored right now because they are not kept in metadata.
+    /// Foreign parent modules are used for resolving names used by foreign macros with def-site
+    /// hygiene, therefore block module ignorability relies on macros with def-site hygiene and
+    /// block module parents being unreachable from other crates.
+    /// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
+    /// but they cannot use def-site hygiene, so the assumption holds
+    /// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
+    fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'a> {
+        loop {
+            match self.get_module(def_id) {
+                Some(module) => return module,
+                None => {
+                    def_id.index =
+                        self.def_key(def_id).parent.expect("non-root `DefId` without parent")
+                }
+            }
         }
-        self.get_module(parent_id)
     }
 
-    pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
-        // If this is a local module, it will be in `module_map`, no need to recalculate it.
-        if let Some(def_id) = def_id.as_local() {
-            return self.module_map[&def_id];
-        }
+    pub fn expect_module(&mut self, def_id: DefId) -> Module<'a> {
+        self.get_module(def_id).expect("argument `DefId` is not a module")
+    }
 
-        // Cache module resolution
-        if let Some(&module) = self.extern_module_map.get(&def_id) {
-            return module;
+    /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
+    /// or trait), then this function returns that module's resolver representation, otherwise it
+    /// returns `None`.
+    /// FIXME: `Module`s for local enums and traits are not currently found.
+    crate fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
+        if let module @ Some(..) = self.module_map.get(&def_id) {
+            return module.copied();
         }
 
-        let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
-            // This is the crate root
-            (self.cstore().crate_name(def_id.krate), None)
-        } else {
-            let def_key = self.cstore().def_key(def_id);
-            let name = def_key
-                .disambiguated_data
-                .data
-                .get_opt_name()
-                .expect("given a DefId that wasn't a module");
-
-            let parent = Some(self.nearest_parent_mod(def_id));
-            (name, parent)
-        };
+        if !def_id.is_local() {
+            let def_kind = self.cstore().def_kind(def_id);
+            match def_kind {
+                DefKind::Mod | DefKind::Enum | DefKind::Trait => {
+                    let def_key = self.cstore().def_key(def_id);
+                    let parent = def_key.parent.map(|index| {
+                        self.get_nearest_non_block_module(DefId { index, krate: def_id.krate })
+                    });
+                    let name = if def_id.index == CRATE_DEF_INDEX {
+                        self.cstore().crate_name(def_id.krate)
+                    } else {
+                        def_key.disambiguated_data.data.get_opt_name().expect("module without name")
+                    };
 
-        // Allocate and return a new module with the information we found
-        let kind = ModuleKind::Def(DefKind::Mod, def_id, name);
-        let module = self.arenas.alloc_module(ModuleData::new(
-            parent,
-            kind,
-            def_id,
-            self.cstore().module_expansion_untracked(def_id, &self.session),
-            self.cstore().get_span_untracked(def_id, &self.session),
-        ));
-        self.extern_module_map.insert(def_id, module);
-        module
+                    let module = self.arenas.new_module(
+                        parent,
+                        ModuleKind::Def(def_kind, def_id, name),
+                        self.cstore().module_expansion_untracked(def_id, &self.session),
+                        self.cstore().get_span_untracked(def_id, &self.session),
+                        // FIXME: Account for `#[no_implicit_prelude]` attributes.
+                        parent.map_or(false, |module| module.no_implicit_prelude),
+                    );
+                    self.module_map.insert(def_id, module);
+                    Some(module)
+                }
+                _ => None,
+            }
+        } else {
+            None
+        }
     }
 
-    crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
-        let def_id = match expn_id.expn_data().macro_def_id {
-            Some(def_id) => def_id,
-            None => {
-                return expn_id
-                    .as_local()
-                    .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id))
-                    .unwrap_or(&self.graph_root);
-            }
-        };
-        self.macro_def_scope_from_def_id(def_id)
+    crate fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
+        match expn_id.expn_data().macro_def_id {
+            Some(def_id) => self.macro_def_scope(def_id),
+            None => expn_id
+                .as_local()
+                .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id))
+                .unwrap_or(&self.graph_root),
+        }
     }
 
-    crate fn macro_def_scope_from_def_id(&mut self, def_id: DefId) -> Module<'a> {
+    crate fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> {
         if let Some(id) = def_id.as_local() {
             self.local_macro_def_scopes[&id]
         } else {
-            // This is not entirely correct - a `macro_rules!` macro may occur
-            // inside a 'block' module:
-            //
-            // ```rust
-            // const _: () = {
-            // #[macro_export]
-            // macro_rules! my_macro {
-            //     () => {};
-            // }
-            // `
-            // We don't record this information for external crates, so
-            // the module we compute here will be the closest 'mod' item
-            // (not necesssarily the actual parent of the `macro_rules!`
-            // macro). `macro_rules!` macros can't use def-site hygiene,
-            // so this hopefully won't be a problem.
-            //
-            // See https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508
-            self.nearest_parent_mod(def_id)
+            self.get_nearest_non_block_module(def_id)
         }
     }
 
@@ -274,7 +265,7 @@ fn resolve_visibility_speculative<'ast>(
                         self.r.visibilities[&def_id.expect_local()]
                     }
                     // Otherwise, the visibility is restricted to the nearest parent `mod` item.
-                    _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod),
+                    _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()),
                 })
             }
             ast::VisibilityKind::Restricted { ref path, id, .. } => {
@@ -717,7 +708,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
                         local_def_id,
                     );
                     self.r.extern_crate_map.insert(local_def_id, crate_id);
-                    self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
+                    self.r.expect_module(crate_id.as_def_id())
                 };
 
                 let used = self.process_macro_use_imports(item, module);
@@ -768,21 +759,16 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
             }
 
             ItemKind::Mod(..) => {
-                let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
-                let module = self.r.arenas.alloc_module(ModuleData {
-                    no_implicit_prelude: parent.no_implicit_prelude || {
-                        self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude)
-                    },
-                    ..ModuleData::new(
-                        Some(parent),
-                        module_kind,
-                        def_id,
-                        expansion.to_expn_id(),
-                        item.span,
-                    )
-                });
+                let module = self.r.arenas.new_module(
+                    Some(parent),
+                    ModuleKind::Def(DefKind::Mod, def_id, ident.name),
+                    expansion.to_expn_id(),
+                    item.span,
+                    parent.no_implicit_prelude
+                        || self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude),
+                );
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
-                self.r.module_map.insert(local_def_id, module);
+                self.r.module_map.insert(def_id, module);
 
                 // Descend into the module.
                 self.parent_scope.module = module;
@@ -813,13 +799,12 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
             }
 
             ItemKind::Enum(_, _) => {
-                let module_kind = ModuleKind::Def(DefKind::Enum, def_id, ident.name);
-                let module = self.r.new_module(
-                    parent,
-                    module_kind,
-                    parent.nearest_parent_mod,
+                let module = self.r.arenas.new_module(
+                    Some(parent),
+                    ModuleKind::Def(DefKind::Enum, def_id, ident.name),
                     expansion.to_expn_id(),
                     item.span,
+                    parent.no_implicit_prelude,
                 );
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.parent_scope.module = module;
@@ -888,13 +873,12 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
 
             ItemKind::Trait(..) => {
                 // Add all the items within to a new module.
-                let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
-                let module = self.r.new_module(
-                    parent,
-                    module_kind,
-                    parent.nearest_parent_mod,
+                let module = self.r.arenas.new_module(
+                    Some(parent),
+                    ModuleKind::Def(DefKind::Trait, def_id, ident.name),
                     expansion.to_expn_id(),
                     item.span,
+                    parent.no_implicit_prelude,
                 );
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.parent_scope.module = module;
@@ -932,12 +916,12 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
         let parent = self.parent_scope.module;
         let expansion = self.parent_scope.expansion;
         if self.block_needs_anonymous_module(block) {
-            let module = self.r.new_module(
-                parent,
+            let module = self.r.arenas.new_module(
+                Some(parent),
                 ModuleKind::Block(block.id),
-                parent.nearest_parent_mod,
                 expansion.to_expn_id(),
                 block.span,
+                parent.no_implicit_prelude,
             );
             self.r.block_map.insert(block.id, module);
             self.parent_scope.module = module; // Descend into the block.
@@ -953,12 +937,13 @@ fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
         // Record primary definitions.
         match res {
             Res::Def(kind @ (DefKind::Mod | DefKind::Enum | DefKind::Trait), def_id) => {
-                let module = self.r.new_module(
-                    parent,
+                let module = self.r.arenas.new_module(
+                    Some(parent),
                     ModuleKind::Def(kind, def_id, ident.name),
-                    def_id,
                     expansion.to_expn_id(),
                     span,
+                    // FIXME: Account for `#[no_implicit_prelude]` attributes.
+                    parent.no_implicit_prelude,
                 );
                 self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
             }
index 0b1687d1bd8c3d4dbbdcc6103cae85eddae5a9f7..d6ff5a7e90b2173a2d2081a22db86aa7d11c202c 100644 (file)
@@ -915,8 +915,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
                     continue;
                 }
                 if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name) {
-                    let crate_root =
-                        self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+                    let crate_root = self.expect_module(crate_id.as_def_id());
                     suggestions.extend(self.lookup_import_candidates_from_module(
                         lookup_ident,
                         namespace,
@@ -1707,6 +1706,9 @@ fn find_span_immediately_after_crate_name(
         candidates.iter().map(|c| path_names_to_string(&c.path)).collect();
 
     path_strings.sort();
+    let core_path_strings =
+        path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
+    path_strings.extend(core_path_strings);
     path_strings.dedup();
 
     let (determiner, kind) = if candidates.len() == 1 {
index d4782edbc134645305d35091a0c252aa6b163de8..7556f69c39116f7993abeb3d7b87fc6d2dce04eb 100644 (file)
@@ -427,7 +427,7 @@ impl<'a> Resolver<'a> {
             match ident.span.glob_adjust(module.expansion, glob_import.span) {
                 Some(Some(def)) => {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
+                        ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
                 Some(None) => {}
@@ -585,7 +585,7 @@ fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F)
         for import in module.glob_importers.borrow_mut().iter() {
             let mut ident = key.ident;
             let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) {
-                Some(Some(def)) => self.macro_def_scope(def),
+                Some(Some(def)) => self.expn_def_scope(def),
                 Some(None) => import.parent_scope.module,
                 None => continue,
             };
@@ -1364,7 +1364,7 @@ fn resolve_glob_import(&mut self, import: &'b Import<'b>) {
             .collect::<Vec<_>>();
         for (mut key, binding) in bindings {
             let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
-                Some(Some(def)) => self.r.macro_def_scope(def),
+                Some(Some(def)) => self.r.expn_def_scope(def),
                 Some(None) => import.parent_scope.module,
                 None => continue,
             };
index c0b52d21fa639c293987ce4779a9158e9f261d53..3c48a76224fd964f8d750978ee035f80223d4452 100644 (file)
@@ -799,9 +799,7 @@ fn with_rib<T>(
     }
 
     fn with_scope<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
-        let id = self.r.local_def_id(id);
-        let module = self.r.module_map.get(&id).cloned(); // clones a reference
-        if let Some(module) = module {
+        if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
             // Move down in the graph.
             let orig_module = replace(&mut self.parent_scope.module, module);
             self.with_rib(ValueNS, ModuleRibKind(module), |this| {
@@ -1872,7 +1870,7 @@ fn smart_resolve_path_fragment(
             if this.should_report_errs() {
                 let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res);
 
-                let def_id = this.parent_scope.module.nearest_parent_mod;
+                let def_id = this.parent_scope.module.nearest_parent_mod();
                 let instead = res.is_some();
                 let suggestion =
                     if res.is_none() { this.report_missing_type_error(path) } else { None };
@@ -1940,7 +1938,7 @@ fn smart_resolve_path_fragment(
 
             drop(parent_err);
 
-            let def_id = this.parent_scope.module.nearest_parent_mod;
+            let def_id = this.parent_scope.module.nearest_parent_mod();
 
             if this.should_report_errs() {
                 this.r.use_injections.push(UseError {
index a158e0e48e86ca616c27024ac1a25e0c1f451013..84e7c68713f231d9b231489943ba24d4fa7b2d3d 100644 (file)
@@ -522,8 +522,7 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
         _ => {}
     }
     let item = {
-        let hir = tcx.hir();
-        let mut parent_iter = hir.parent_iter(hir_id);
+        let mut parent_iter = tcx.hir().parent_iter(hir_id);
         loop {
             let node = parent_iter.next().map(|n| n.1);
             match node {
index d76ba80e42eab75a95eeddd5a836b802714ab616..1cbe8f41d92b0704714e881bc02613765f9dbffd 100644 (file)
@@ -10,6 +10,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(box_patterns)]
+#![feature(drain_filter)]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
 #![feature(format_args_capture)]
@@ -40,7 +41,8 @@
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
 use rustc_hir::def::Namespace::*;
 use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId};
+use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
 use rustc_hir::TraitCandidate;
 use rustc_index::vec::IndexVec;
@@ -505,10 +507,6 @@ pub struct ModuleData<'a> {
     /// What kind of module this is, because this may not be a `mod`.
     kind: ModuleKind,
 
-    /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
-    /// This may be the crate root.
-    nearest_parent_mod: DefId,
-
     /// Mapping between names and their (possibly in-progress) resolutions in this module.
     /// Resolutions in modules from other crates are not populated until accessed.
     lazy_resolutions: Resolutions<'a>,
@@ -539,18 +537,21 @@ impl<'a> ModuleData<'a> {
     fn new(
         parent: Option<Module<'a>>,
         kind: ModuleKind,
-        nearest_parent_mod: DefId,
         expansion: ExpnId,
         span: Span,
+        no_implicit_prelude: bool,
     ) -> Self {
+        let is_foreign = match kind {
+            ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
+            ModuleKind::Block(_) => false,
+        };
         ModuleData {
             parent,
             kind,
-            nearest_parent_mod,
             lazy_resolutions: Default::default(),
-            populate_on_access: Cell::new(!nearest_parent_mod.is_local()),
+            populate_on_access: Cell::new(is_foreign),
             unexpanded_invocations: Default::default(),
-            no_implicit_prelude: false,
+            no_implicit_prelude,
             glob_importers: RefCell::new(Vec::new()),
             globs: RefCell::new(Vec::new()),
             traits: RefCell::new(None),
@@ -623,6 +624,15 @@ fn nearest_item_scope(&'a self) -> Module<'a> {
         }
     }
 
+    /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
+    /// This may be the crate root.
+    fn nearest_parent_mod(&self) -> DefId {
+        match self.kind {
+            ModuleKind::Def(DefKind::Mod, def_id, _) => def_id,
+            _ => self.parent.expect("non-root module without parent").nearest_parent_mod(),
+        }
+    }
+
     fn is_ancestor_of(&self, mut other: &Self) -> bool {
         while !ptr::eq(self, other) {
             if let Some(parent) = other.parent {
@@ -934,8 +944,7 @@ pub struct Resolver<'a> {
     /// some AST passes can generate identifiers that only resolve to local or
     /// language items.
     empty_module: Module<'a>,
-    module_map: FxHashMap<LocalDefId, Module<'a>>,
-    extern_module_map: FxHashMap<DefId, Module<'a>>,
+    module_map: FxHashMap<DefId, Module<'a>>,
     binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
     underscore_disambiguator: u32,
 
@@ -1052,8 +1061,16 @@ pub struct ResolverArenas<'a> {
 }
 
 impl<'a> ResolverArenas<'a> {
-    fn alloc_module(&'a self, module: ModuleData<'a>) -> Module<'a> {
-        let module = self.modules.alloc(module);
+    fn new_module(
+        &'a self,
+        parent: Option<Module<'a>>,
+        kind: ModuleKind,
+        expn_id: ExpnId,
+        span: Span,
+        no_implicit_prelude: bool,
+    ) -> Module<'a> {
+        let module =
+            self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude));
         if module.def_id().map_or(true, |def_id| def_id.is_local()) {
             self.local_modules.borrow_mut().push(module);
         }
@@ -1255,32 +1272,29 @@ pub fn new(
         metadata_loader: Box<MetadataLoaderDyn>,
         arenas: &'a ResolverArenas<'a>,
     ) -> Resolver<'a> {
-        let root_local_def_id = LocalDefId { local_def_index: CRATE_DEF_INDEX };
-        let root_def_id = root_local_def_id.to_def_id();
-        let root_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
-        let graph_root = arenas.alloc_module(ModuleData {
-            no_implicit_prelude: session.contains_name(&krate.attrs, sym::no_implicit_prelude),
-            ..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
-        });
-        let empty_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
-        let empty_module = arenas.alloc_module(ModuleData {
-            no_implicit_prelude: true,
-            ..ModuleData::new(
-                Some(graph_root),
-                empty_module_kind,
-                root_def_id,
-                ExpnId::root(),
-                DUMMY_SP,
-            )
-        });
+        let root_def_id = CRATE_DEF_ID.to_def_id();
+        let graph_root = arenas.new_module(
+            None,
+            ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+            ExpnId::root(),
+            krate.span,
+            session.contains_name(&krate.attrs, sym::no_implicit_prelude),
+        );
+        let empty_module = arenas.new_module(
+            None,
+            ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+            ExpnId::root(),
+            DUMMY_SP,
+            true,
+        );
         let mut module_map = FxHashMap::default();
-        module_map.insert(root_local_def_id, graph_root);
+        module_map.insert(root_def_id, graph_root);
 
         let definitions = Definitions::new(session.local_stable_crate_id(), krate.span);
         let root = definitions.get_root_def();
 
         let mut visibilities = FxHashMap::default();
-        visibilities.insert(root_local_def_id, ty::Visibility::Public);
+        visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public);
 
         let mut def_id_to_node_id = IndexVec::default();
         assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root);
@@ -1341,7 +1355,6 @@ pub fn new(
             empty_module,
             module_map,
             block_map: Default::default(),
-            extern_module_map: FxHashMap::default(),
             binding_parent_modules: FxHashMap::default(),
             ast_transform_scopes: FxHashMap::default(),
 
@@ -1632,18 +1645,6 @@ fn find_transitive_imports(
         import_ids
     }
 
-    fn new_module(
-        &self,
-        parent: Module<'a>,
-        kind: ModuleKind,
-        nearest_parent_mod: DefId,
-        expn_id: ExpnId,
-        span: Span,
-    ) -> Module<'a> {
-        let module = ModuleData::new(Some(parent), kind, nearest_parent_mod, expn_id, span);
-        self.arenas.alloc_module(module)
-    }
-
     fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
         let ident = ident.normalize_to_macros_2_0();
         let disambiguator = if ident.name == kw::Underscore {
@@ -2016,7 +2017,7 @@ fn hygienic_lexical_parent(
         derive_fallback_lint_id: Option<NodeId>,
     ) -> Option<(Module<'a>, Option<NodeId>)> {
         if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
-            return Some((self.macro_def_scope(ctxt.remove_mark()), None));
+            return Some((self.expn_def_scope(ctxt.remove_mark()), None));
         }
 
         if let ModuleKind::Block(..) = module.kind {
@@ -2085,7 +2086,7 @@ fn resolve_ident_in_module_ext(
             ModuleOrUniformRoot::Module(m) => {
                 if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
+                        ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
             }
@@ -2158,7 +2159,7 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
             ctxt.adjust(ExpnId::root())
         };
         let module = match mark {
-            Some(def) => self.macro_def_scope(def),
+            Some(def) => self.expn_def_scope(def),
             None => {
                 debug!(
                     "resolve_crate_root({:?}): found no mark (ident.span = {:?})",
@@ -2167,7 +2168,8 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
                 return self.graph_root;
             }
         };
-        let module = self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.nearest_parent_mod });
+        let module = self
+            .expect_module(module.def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id());
         debug!(
             "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
             ident,
@@ -2179,10 +2181,10 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
     }
 
     fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
-        let mut module = self.get_module(module.nearest_parent_mod);
+        let mut module = self.expect_module(module.nearest_parent_mod());
         while module.span.ctxt().normalize_to_macros_2_0() != *ctxt {
-            let parent = module.parent.unwrap_or_else(|| self.macro_def_scope(ctxt.remove_mark()));
-            module = self.get_module(parent.nearest_parent_mod);
+            let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark()));
+            module = self.expect_module(parent.nearest_parent_mod());
         }
         module
     }
@@ -2896,7 +2898,7 @@ fn record_pat_span(&mut self, node: NodeId, span: Span) {
     }
 
     fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
-        vis.is_accessible_from(module.nearest_parent_mod, self)
+        vis.is_accessible_from(module.nearest_parent_mod(), self)
     }
 
     fn set_binding_parent_module(&mut self, binding: &'a NameBinding<'a>, module: Module<'a>) {
@@ -2920,7 +2922,7 @@ fn disambiguate_macro_rules_vs_modularized(
             self.binding_parent_modules.get(&PtrKey(modularized)),
         ) {
             (Some(macro_rules), Some(modularized)) => {
-                macro_rules.nearest_parent_mod == modularized.nearest_parent_mod
+                macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
                     && modularized.is_ancestor_of(macro_rules)
             }
             _ => false,
@@ -3265,7 +3267,7 @@ fn extern_prelude_get(
                 } else {
                     self.crate_loader.maybe_process_path_extern(ident.name)?
                 };
-                let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+                let crate_root = self.expect_module(crate_id.as_def_id());
                 Some(
                     (crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT)
                         .to_name_binding(self.arenas),
@@ -3306,7 +3308,7 @@ pub fn resolve_str_path_error(
                 tokens: None,
             }
         };
-        let module = self.get_module(module_id);
+        let module = self.expect_module(module_id);
         let parent_scope = &ParentScope::module(module, self);
         let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
         Ok((path, res))
index 4dbac47c3cc8e35202613a948b6622e5d52a0779..f15cf4bbc3a57cb138a2f4d7ceee244270cf4bf3 100644 (file)
@@ -225,7 +225,8 @@ fn expansion_for_ast_pass(
         features: &[Symbol],
         parent_module_id: Option<NodeId>,
     ) -> LocalExpnId {
-        let parent_module = parent_module_id.map(|module_id| self.local_def_id(module_id));
+        let parent_module =
+            parent_module_id.map(|module_id| self.local_def_id(module_id).to_def_id());
         let expn_id = LocalExpnId::fresh(
             ExpnData::allow_unstable(
                 ExpnKind::AstPass(pass),
@@ -233,13 +234,13 @@ fn expansion_for_ast_pass(
                 self.session.edition(),
                 features.into(),
                 None,
-                parent_module.map(LocalDefId::to_def_id),
+                parent_module,
             ),
             self.create_stable_hashing_context(),
         );
 
-        let parent_scope = parent_module
-            .map_or(self.empty_module, |parent_def_id| self.module_map[&parent_def_id]);
+        let parent_scope =
+            parent_module.map_or(self.empty_module, |def_id| self.expect_module(def_id));
         self.ast_transform_scopes.insert(expn_id, parent_scope);
 
         expn_id
@@ -298,51 +299,18 @@ fn resolve_macro_invocation(
         )?;
 
         let span = invoc.span();
+        let def_id = res.opt_def_id();
         invoc_id.set_expn_data(
             ext.expn_data(
                 parent_scope.expansion,
                 span,
                 fast_print_path(path),
-                res.opt_def_id(),
-                res.opt_def_id().map(|macro_def_id| {
-                    self.macro_def_scope_from_def_id(macro_def_id).nearest_parent_mod
-                }),
+                def_id,
+                def_id.map(|def_id| self.macro_def_scope(def_id).nearest_parent_mod()),
             ),
             self.create_stable_hashing_context(),
         );
 
-        if let Res::Def(_, _) = res {
-            // Gate macro attributes in `#[derive]` output.
-            if !self.session.features_untracked().macro_attributes_in_derive_output
-                && kind == MacroKind::Attr
-                && ext.builtin_name != Some(sym::derive)
-            {
-                let mut expn_id = parent_scope.expansion;
-                loop {
-                    // Helper attr table is a quick way to determine whether the attr is `derive`.
-                    if self.helper_attrs.contains_key(&expn_id) {
-                        feature_err(
-                            &self.session.parse_sess,
-                            sym::macro_attributes_in_derive_output,
-                            path.span,
-                            "macro attributes in `#[derive]` output are unstable",
-                        )
-                        .emit();
-                        break;
-                    } else {
-                        let expn_data = expn_id.expn_data();
-                        match expn_data.kind {
-                            ExpnKind::Root
-                            | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
-                                break;
-                            }
-                            _ => expn_id = expn_data.parent.expect_local(),
-                        }
-                    }
-                }
-            }
-        }
-
         Ok(ext)
     }
 
index 535a48bcda182baf93ad87881c9aabf88f00ce0e..15a89d82fa69626b373cc0eb40bfe7ea8fcfe874 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_save_analysis"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 tracing = "0.1"
index 593a7563e36a2640520c2a493b8545ae2d5c0585..49778f82253bfddf9558b8e49f72fdc2caf4ef49 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_serialize"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 indexmap = "1"
index 5b617a2997cd65b55fcde2f76f94972a09aa1b18..4cff21bee3dc37f4bafbbaa0ea71b87b6c9ff24d 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_session"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 getopts = "0.2"
index d6f4a3ae4f121f76a8594e7662a224f7d057ce79..27215556045be2fe15eddda96a73f816f532262b 100644 (file)
@@ -902,7 +902,12 @@ pub fn consider_optimizing<T: Fn() -> String>(&self, crate_name: &str, msg: T) -
                 let mut fuel = self.optimization_fuel.lock();
                 ret = fuel.remaining != 0;
                 if fuel.remaining == 0 && !fuel.out_of_fuel {
-                    self.warn(&format!("optimization-fuel-exhausted: {}", msg()));
+                    if self.diagnostic().can_emit_warnings() {
+                        // We only call `msg` in case we can actually emit warnings.
+                        // Otherwise, this could cause a `delay_good_path_bug` to
+                        // trigger (issue #79546).
+                        self.warn(&format!("optimization-fuel-exhausted: {}", msg()));
+                    }
                     fuel.out_of_fuel = true;
                 } else if fuel.remaining > 0 {
                     fuel.remaining -= 1;
index e475e89d87e8ec03fb9d2afb174f5745964e9084..781fb8c1e5d8c8644dfe872cdb22943cb76daae1 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_span"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 9c5469f635f71ee8c3f6d136d9b60f19242ea749..032ae73bbf3c61fe503de4442584f5fc658a0e2b 100644 (file)
@@ -25,6 +25,9 @@
 #[macro_use]
 extern crate rustc_macros;
 
+#[macro_use]
+extern crate tracing;
+
 use rustc_data_structures::AtomicRef;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -782,13 +785,30 @@ pub fn between(self, end: Span) -> Span {
     ///     ^^^^^^^^^^^^^^^^^
     /// ```
     pub fn until(self, end: Span) -> Span {
-        let span = self.data();
-        let end = end.data();
+        // Most of this function's body is copied from `to`.
+        // We can't just do `self.to(end.shrink_to_lo())`,
+        // because to also does some magic where it uses min/max so
+        // it can handle overlapping spans. Some advanced mis-use of
+        // `until` with different ctxts makes this visible.
+        let span_data = self.data();
+        let end_data = end.data();
+        // FIXME(jseyfried): `self.ctxt` should always equal `end.ctxt` here (cf. issue #23480).
+        // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
+        // have an incomplete span than a completely nonsensical one.
+        if span_data.ctxt != end_data.ctxt {
+            if span_data.ctxt == SyntaxContext::root() {
+                return end;
+            } else if end_data.ctxt == SyntaxContext::root() {
+                return self;
+            }
+            // Both spans fall within a macro.
+            // FIXME(estebank): check if it is the *same* macro.
+        }
         Span::new(
-            span.lo,
-            end.lo,
-            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
-            if span.parent == end.parent { span.parent } else { None },
+            span_data.lo,
+            end_data.lo,
+            if end_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
 
index 9e403eb3f67f3de9424a003c1ef56f68b4f899a2..b79f00a8a36425f7dea49abd4ce50b97ee866847 100644 (file)
@@ -474,11 +474,12 @@ pub fn is_multiline(&self, sp: Span) -> bool {
         f.lookup_line(sp.lo()) != f.lookup_line(sp.hi())
     }
 
+    #[instrument(skip(self), level = "trace")]
     pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> {
         let lo = self.lookup_char_pos(sp.lo());
-        debug!("span_to_lines: lo={:?}", lo);
+        trace!(?lo);
         let hi = self.lookup_char_pos(sp.hi());
-        debug!("span_to_lines: hi={:?}", hi);
+        trace!(?hi);
         if lo.file.start_pos != hi.file.start_pos {
             return Err(SpanLinesError::DistinctSources(DistinctSources {
                 begin: (lo.file.name.clone(), lo.file.start_pos),
index 322bea3806cfa5eef8695afb484db53b86b6e93c..7cb4e18398cdcddf5cecc90dda0747f30d642349 100644 (file)
         TyCtxt,
         TyKind,
         Unknown,
+        UnsafeArg,
         Vec,
         Yield,
         _DECLS,
         clone_from,
         closure,
         closure_to_fn_coercion,
+        closure_track_caller,
         cmp,
         cmp_max,
         cmp_min,
         mul,
         mul_assign,
         mul_with_overflow,
+        must_not_suspend,
         must_use,
         mut_ptr,
         mut_slice_ptr,
@@ -1615,7 +1618,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 pub struct Symbol(SymbolIndex);
 
 rustc_index::newtype_index! {
-    pub struct SymbolIndex { .. }
+    struct SymbolIndex { .. }
 }
 
 impl Symbol {
@@ -1641,10 +1644,6 @@ pub fn as_u32(self) -> u32 {
         self.0.as_u32()
     }
 
-    pub fn len(self) -> usize {
-        with_session_globals(|session_globals| session_globals.symbol_interner.get(self).len())
-    }
-
     pub fn is_empty(self) -> bool {
         self == kw::Empty
     }
index aebf77a1fd85ffc1e276068968eea533c387f3da..d5befa10e23638f7bd9fd7860284c8d1fa6dae36 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_symbol_mangling"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index e47a84dbc117e4851aecf8d7cc93eaa1db30a1bb..925813e6bb42762ff5887618910312df4e15a215 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_target"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 bitflags = "1.2.1"
index bf3ec8f9160b08aac80284106fdf342b9eef2efc..dc91f1230964921d22bd30924373df7fc78744cf 100644 (file)
@@ -4,7 +4,9 @@ pub fn target() -> Target {
     let mut base = super::apple_base::opts("macos");
     base.cpu = "apple-a12".to_string();
     base.max_atomic_width = Some(128);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
+
+    // FIXME: The leak sanitizer currently fails the tests, see #88132.
+    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
 
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
     base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
index e2c626d1b22071b0e6f0f6e705f69e5e9fe15a37..9a9737362c6c8017bd8063e4b3a6b5ab1704ad4a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_trait_selection"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index 969962e55b0df3e4fb963572e1e3e8b06b321da2..a89796f172c5a588c398ce440034b07936bd2857 100644 (file)
@@ -135,7 +135,7 @@ fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
         let obligation = traits::Obligation::new(
             cause.clone(),
             self.param_env,
-            trait_ref.without_const().to_predicate(tcx),
+            ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
         );
         if !self.infcx.predicate_may_hold(&obligation) {
             debug!("overloaded_deref_ty: cannot match obligation");
index 42cbed600d5bf92229ca6f6ff55002ded9d53d2c..8fb4eb641c26a913af2e04053b1e591babf53452 100644 (file)
@@ -120,7 +120,7 @@ fn type_implements_trait(
             cause: traits::ObligationCause::dummy(),
             param_env,
             recursion_depth: 0,
-            predicate: trait_ref.without_const().to_predicate(self.tcx),
+            predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
         };
         self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
     }
index 8abcdb5e89b47b697091b36183f91408adf28419..028f6e89f18f127eac726cb7177d1ca8d72373ee 100644 (file)
@@ -1,4 +1,3 @@
-use crate::infer::InferCtxtExt as _;
 use crate::traits::{self, ObligationCause, PredicateObligation};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -863,7 +862,6 @@ struct Instantiator<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> Instantiator<'a, 'tcx> {
-    #[instrument(level = "debug", skip(self))]
     fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
         let tcx = self.infcx.tcx;
         value.fold_with(&mut BottomUpFolder {
@@ -954,6 +952,7 @@ fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -
         })
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn fold_opaque_ty(
         &mut self,
         ty: Ty<'tcx>,
@@ -964,25 +963,18 @@ fn fold_opaque_ty(
         let tcx = infcx.tcx;
         let OpaqueTypeKey { def_id, substs } = opaque_type_key;
 
-        debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs);
-
         // Use the same type variable if the exact same opaque type appears more
         // than once in the return type (e.g., if it's passed to a type alias).
         if let Some(opaque_defn) = infcx.inner.borrow().opaque_types.get(&opaque_type_key) {
-            debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty);
+            debug!("re-using cached concrete type {:?}", opaque_defn.concrete_ty.kind());
             return opaque_defn.concrete_ty;
         }
+
         let ty_var = infcx.next_ty_var(TypeVariableOrigin {
             kind: TypeVariableOriginKind::TypeInference,
             span: self.value_span,
         });
 
-        // Make sure that we are in fact defining the *entire* type
-        // (e.g., `type Foo<T: Bound> = impl Bar;` needs to be
-        // defined by a function like `fn foo<T: Bound>() -> Foo<T>`).
-        debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,);
-        debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),);
-
         // Ideally, we'd get the span where *this specific `ty` came
         // from*, but right now we just use the span from the overall
         // value being folded. In simple cases like `-> impl Foo`,
@@ -999,43 +991,40 @@ fn fold_opaque_ty(
             infcx.opaque_types_vars.insert(ty_var, ty);
         }
 
-        debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
-        self.compute_opaque_type_obligations(opaque_type_key);
-
-        ty_var
-    }
-
-    fn compute_opaque_type_obligations(&mut self, opaque_type_key: OpaqueTypeKey<'tcx>) {
-        let infcx = self.infcx;
-        let tcx = infcx.tcx;
-        let OpaqueTypeKey { def_id, substs } = opaque_type_key;
+        debug!("generated new type inference var {:?}", ty_var.kind());
 
         let item_bounds = tcx.explicit_item_bounds(def_id);
-        debug!("instantiate_opaque_types: bounds={:#?}", item_bounds);
-        let bounds: Vec<_> =
-            item_bounds.iter().map(|(bound, _)| bound.subst(tcx, substs)).collect();
-
-        let param_env = tcx.param_env(def_id);
-        let InferOk { value: bounds, obligations } = infcx.partially_normalize_associated_types_in(
-            ObligationCause::misc(self.value_span, self.body_id),
-            param_env,
-            bounds,
-        );
-        self.obligations.extend(obligations);
 
-        debug!("instantiate_opaque_types: bounds={:?}", bounds);
+        self.obligations.reserve(item_bounds.len());
+        for (predicate, _) in item_bounds {
+            debug!(?predicate);
+            let predicate = predicate.subst(tcx, substs);
+            debug!(?predicate);
+
+            // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
+            let predicate = predicate.fold_with(&mut BottomUpFolder {
+                tcx,
+                ty_op: |ty| match ty.kind() {
+                    ty::Projection(projection_ty) => infcx.infer_projection(
+                        self.param_env,
+                        *projection_ty,
+                        ObligationCause::misc(self.value_span, self.body_id),
+                        0,
+                        &mut self.obligations,
+                    ),
+                    _ => ty,
+                },
+                lt_op: |lt| lt,
+                ct_op: |ct| ct,
+            });
+            debug!(?predicate);
 
-        for predicate in &bounds {
             if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
                 if projection.ty.references_error() {
                     // No point on adding these obligations since there's a type error involved.
-                    return;
+                    return tcx.ty_error();
                 }
             }
-        }
-
-        self.obligations.reserve(bounds.len());
-        for predicate in bounds {
             // Change the predicate to refer to the type variable,
             // which will be the concrete type instead of the opaque type.
             // This also instantiates nested instances of `impl Trait`.
@@ -1045,9 +1034,11 @@ fn compute_opaque_type_obligations(&mut self, opaque_type_key: OpaqueTypeKey<'tc
                 traits::ObligationCause::new(self.value_span, self.body_id, traits::OpaqueType);
 
             // Require that the predicate holds for the concrete type.
-            debug!("instantiate_opaque_types: predicate={:?}", predicate);
+            debug!(?predicate);
             self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate));
         }
+
+        ty_var
     }
 }
 
@@ -1071,11 +1062,7 @@ fn compute_opaque_type_obligations(&mut self, opaque_type_key: OpaqueTypeKey<'tc
 /// Here, `def_id` is the `LocalDefId` of the defining use of the opaque type (e.g., `f1` or `f2`),
 /// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`.
 /// For the above example, this function returns `true` for `f1` and `false` for `f2`.
-pub fn may_define_opaque_type(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-    opaque_hir_id: hir::HirId,
-) -> bool {
+fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool {
     let mut hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
     // Named opaque types can be defined by any siblings or children of siblings.
index 9c962d30ce0e8b8a575627173b019c993dee5b16..ec62ee400688ca2f62cae140fc32b1f40da8bf5e 100644 (file)
@@ -7,16 +7,21 @@
     ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, ObligationCause,
     PredicateObligation, SelectionError, TraitEngine,
 };
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_middle::ty::{self, Ty};
 
 pub struct FulfillmentContext<'tcx> {
     obligations: FxIndexSet<PredicateObligation<'tcx>>,
+
+    relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
 }
 
 impl FulfillmentContext<'tcx> {
     crate fn new() -> Self {
-        FulfillmentContext { obligations: FxIndexSet::default() }
+        FulfillmentContext {
+            obligations: FxIndexSet::default(),
+            relationships: FxHashMap::default(),
+        }
     }
 }
 
@@ -39,6 +44,8 @@ fn register_predicate_obligation(
         assert!(!infcx.is_in_snapshot());
         let obligation = infcx.resolve_vars_if_possible(obligation);
 
+        super::relationships::update(self, infcx, &obligation);
+
         self.obligations.insert(obligation);
     }
 
@@ -146,4 +153,8 @@ fn select_where_possible(
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
         self.obligations.iter().cloned().collect()
     }
+
+    fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
+        &mut self.relationships
+    }
 }
index ae61988928f78e6ba2f317016718c2cf1df01c3f..9d1f409d69c665285be51a558fcfc54581800172 100644 (file)
@@ -726,7 +726,7 @@ fn suggest_add_reference_to_arg(
             let new_obligation = Obligation::new(
                 ObligationCause::dummy(),
                 param_env,
-                new_trait_ref.without_const().to_predicate(self.tcx),
+                ty::Binder::dummy(new_trait_ref).without_const().to_predicate(self.tcx),
             );
 
             if self.predicate_must_hold_modulo_regions(&new_obligation) {
index b376f4292924963574d690c85d6426119479fa89..465d1465d5d3538325def6ae9dcf226b730f9aa6 100644 (file)
@@ -1,4 +1,5 @@
 use crate::infer::{InferCtxt, TyOrConstInferVar};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::obligation_forest::ProcessResult;
 use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
 use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
@@ -53,6 +54,9 @@ pub struct FulfillmentContext<'tcx> {
     // A list of all obligations that have been registered with this
     // fulfillment context.
     predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
+
+    relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
+
     // Should this fulfillment context register type-lives-for-region
     // obligations on its parent infcx? In some cases, region
     // obligations are either already known to hold (normalization) or
@@ -97,6 +101,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
     pub fn new() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
+            relationships: FxHashMap::default(),
             register_region_obligations: true,
             usable_in_snapshot: false,
         }
@@ -105,6 +110,7 @@ pub fn new() -> FulfillmentContext<'tcx> {
     pub fn new_in_snapshot() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
+            relationships: FxHashMap::default(),
             register_region_obligations: true,
             usable_in_snapshot: true,
         }
@@ -113,6 +119,7 @@ pub fn new_in_snapshot() -> FulfillmentContext<'tcx> {
     pub fn new_ignoring_regions() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
+            relationships: FxHashMap::default(),
             register_region_obligations: false,
             usable_in_snapshot: false,
         }
@@ -210,6 +217,8 @@ fn register_predicate_obligation(
 
         assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot);
 
+        super::relationships::update(self, infcx, &obligation);
+
         self.predicates
             .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
     }
@@ -265,6 +274,10 @@ fn select_with_constness_where_possible(
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
         self.predicates.map_pending_obligations(|o| o.obligation.clone())
     }
+
+    fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
+        &mut self.relationships
+    }
 }
 
 struct FulfillProcessor<'a, 'b, 'tcx> {
@@ -405,7 +418,8 @@ fn progress_changed_obligations(
                 | ty::PredicateKind::Coerce(_)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::ConstEquate(..) => {
-                    let pred = infcx.replace_bound_vars_with_placeholders(binder);
+                    let pred =
+                        ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
                     ProcessResult::Changed(mk_pending(vec![
                         obligation.with(pred.to_predicate(self.selcx.tcx())),
                     ]))
index ef208c44471cbadf52d2b5dcdea6af83fc019092..b3c9cf4c173ecdc72fb2c3a12354b7eb3bff8594 100644 (file)
@@ -15,6 +15,7 @@
 mod on_unimplemented;
 mod project;
 pub mod query;
+pub(crate) mod relationships;
 mod select;
 mod specialize;
 mod structural_match;
@@ -139,7 +140,8 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
         infcx.tcx.def_path_str(def_id)
     );
 
-    let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
+    let trait_ref =
+        ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) });
     let obligation = Obligation {
         param_env,
         cause: ObligationCause::misc(span, hir::CRATE_HIR_ID),
index 4922cf45a4a109565db5478fb7b53c8a3b5c3e8d..0bb00dfeb43ad92fd54f6d035dd4d545403df7f7 100644 (file)
@@ -250,7 +250,7 @@ fn predicates_reference_self(
     trait_def_id: DefId,
     supertraits_only: bool,
 ) -> SmallVec<[Span; 1]> {
-    let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
+    let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
     let predicates = if supertraits_only {
         tcx.super_predicates_of(trait_def_id)
     } else {
@@ -554,11 +554,11 @@ fn object_ty_for_trait<'tcx>(
 
     let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
 
-    let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait(
-        ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
-    ));
+    let trait_predicate = trait_ref.map_bound(|trait_ref| {
+        ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
+    });
 
-    let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref))
+    let mut associated_types = traits::supertraits(tcx, trait_ref)
         .flat_map(|super_trait_ref| {
             tcx.associated_items(super_trait_ref.def_id())
                 .in_definition_order()
@@ -671,10 +671,10 @@ fn receiver_is_dispatchable<'tcx>(
         let param_env = tcx.param_env(method.def_id);
 
         // Self: Unsize<U>
-        let unsize_predicate = ty::TraitRef {
+        let unsize_predicate = ty::Binder::dummy(ty::TraitRef {
             def_id: unsize_did,
             substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
-        }
+        })
         .without_const()
         .to_predicate(tcx);
 
@@ -689,7 +689,9 @@ fn receiver_is_dispatchable<'tcx>(
                     }
                 });
 
-            ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate(tcx)
+            ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs })
+                .without_const()
+                .to_predicate(tcx)
         };
 
         let caller_bounds: Vec<Predicate<'tcx>> = param_env
@@ -703,10 +705,10 @@ fn receiver_is_dispatchable<'tcx>(
 
     // Receiver: DispatchFromDyn<Receiver[Self => U]>
     let obligation = {
-        let predicate = ty::TraitRef {
+        let predicate = ty::Binder::dummy(ty::TraitRef {
             def_id: dispatch_from_dyn_did,
             substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
-        }
+        })
         .without_const()
         .to_predicate(tcx);
 
@@ -789,8 +791,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
 
                     // Compute supertraits of current trait lazily.
                     if self.supertraits.is_none() {
-                        let trait_ref =
-                            ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id));
+                        let trait_ref = ty::TraitRef::identity(self.tcx, self.trait_def_id);
                         self.supertraits = Some(
                             traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(),
                         );
index 4f22543950c0bf5785e00c10383b34c5b4879f3e..baf6b725648df4b0bd7209a47177f555b4305834 100644 (file)
@@ -27,7 +27,7 @@
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
 use rustc_middle::ty::subst::Subst;
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_span::symbol::sym;
 
 use std::collections::BTreeMap;
@@ -810,17 +810,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
         // and a deferred predicate to resolve this when more type
         // information is available.
 
-        let tcx = selcx.infcx().tcx;
-        let def_id = projection_ty.item_def_id;
-        let ty_var = selcx.infcx().next_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::NormalizeProjectionType,
-            span: tcx.def_span(def_id),
-        });
-        let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
-        let obligation =
-            Obligation::with_depth(cause, depth + 1, param_env, projection.to_predicate(tcx));
-        obligations.push(obligation);
-        ty_var
+        selcx.infcx().infer_projection(param_env, projection_ty, cause, depth + 1, obligations)
     })
 }
 
@@ -844,6 +834,10 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
     obligations: &mut Vec<PredicateObligation<'tcx>>,
 ) -> Result<Option<Ty<'tcx>>, InProgress> {
     let infcx = selcx.infcx();
+    // Don't use the projection cache in intercrate mode -
+    // the `infcx` may be re-used between intercrate in non-intercrate
+    // mode, which could lead to using incorrect cache results.
+    let use_cache = !selcx.is_intercrate();
 
     let projection_ty = infcx.resolve_vars_if_possible(projection_ty);
     let cache_key = ProjectionCacheKey::new(projection_ty);
@@ -856,7 +850,11 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
     // bounds. It might be the case that we want two distinct caches,
     // or else another kind of cache entry.
 
-    let cache_result = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
+    let cache_result = if use_cache {
+        infcx.inner.borrow_mut().projection_cache().try_start(cache_key)
+    } else {
+        Ok(())
+    };
     match cache_result {
         Ok(()) => debug!("no cache"),
         Err(ProjectionCacheEntry::Ambiguous) => {
@@ -881,7 +879,9 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
             // should ensure that, unless this happens within a snapshot that's
             // rolled back, fulfillment or evaluation will notice the cycle.
 
-            infcx.inner.borrow_mut().projection_cache().recur(cache_key);
+            if use_cache {
+                infcx.inner.borrow_mut().projection_cache().recur(cache_key);
+            }
             return Err(InProgress);
         }
         Err(ProjectionCacheEntry::Recur) => {
@@ -963,20 +963,26 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
                         .map_or(false, |res| res.must_apply_considering_regions())
             });
 
-            infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
+            if use_cache {
+                infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
+            }
             obligations.extend(result.obligations);
             Ok(Some(result.value))
         }
         Ok(ProjectedTy::NoProgress(projected_ty)) => {
             debug!(?projected_ty, "opt_normalize_projection_type: no progress");
             let result = Normalized { value: projected_ty, obligations: vec![] };
-            infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
+            if use_cache {
+                infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
+            }
             // No need to extend `obligations`.
             Ok(Some(result.value))
         }
         Err(ProjectionTyError::TooManyCandidates) => {
             debug!("opt_normalize_projection_type: too many candidates");
-            infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
+            if use_cache {
+                infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
+            }
             Ok(None)
         }
         Err(ProjectionTyError::TraitSelectionError(_)) => {
@@ -986,7 +992,9 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
             // Trait`, which when processed will cause the error to be
             // reported later
 
-            infcx.inner.borrow_mut().projection_cache().error(cache_key);
+            if use_cache {
+                infcx.inner.borrow_mut().projection_cache().error(cache_key);
+            }
             let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
             obligations.extend(result.obligations);
             Ok(Some(result.value))
@@ -1020,7 +1028,7 @@ fn normalize_to_error<'a, 'tcx>(
     cause: ObligationCause<'tcx>,
     depth: usize,
 ) -> NormalizedTy<'tcx> {
-    let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref();
+    let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx()));
     let trait_obligation = Obligation {
         cause,
         recursion_depth: depth,
@@ -1282,7 +1290,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
 
     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
     // start out by selecting the predicate `T as TraitRef<...>`:
-    let poly_trait_ref = obligation.predicate.trait_ref(selcx.tcx()).to_poly_trait_ref();
+    let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
     let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
     let _ = selcx.infcx().commit_if_ok(|_| {
         let impl_source = match selcx.select(&trait_obligation) {
diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs
new file mode 100644 (file)
index 0000000..7751dd8
--- /dev/null
@@ -0,0 +1,69 @@
+use crate::infer::InferCtxt;
+use crate::traits::query::evaluate_obligation::InferCtxtExt;
+use crate::traits::{ObligationCause, PredicateObligation};
+use rustc_infer::traits::TraitEngine;
+use rustc_middle::ty::{self, ToPredicate};
+
+pub(crate) fn update<'tcx, T>(
+    engine: &mut T,
+    infcx: &InferCtxt<'_, 'tcx>,
+    obligation: &PredicateObligation<'tcx>,
+) where
+    T: TraitEngine<'tcx>,
+{
+    // (*) binder skipped
+    if let ty::PredicateKind::Trait(predicate) = obligation.predicate.kind().skip_binder() {
+        if let Some(ty) =
+            infcx.shallow_resolve(predicate.self_ty()).ty_vid().map(|t| infcx.root_var(t))
+        {
+            if infcx
+                .tcx
+                .lang_items()
+                .sized_trait()
+                .map_or(false, |st| st != predicate.trait_ref.def_id)
+            {
+                let new_self_ty = infcx.tcx.types.unit;
+
+                let trait_ref = ty::TraitRef {
+                    substs: infcx
+                        .tcx
+                        .mk_substs_trait(new_self_ty, &predicate.trait_ref.substs[1..]),
+                    ..predicate.trait_ref
+                };
+
+                // Then contstruct a new obligation with Self = () added
+                // to the ParamEnv, and see if it holds.
+                let o = rustc_infer::traits::Obligation::new(
+                    ObligationCause::dummy(),
+                    obligation.param_env,
+                    obligation
+                        .predicate
+                        .kind()
+                        .map_bound(|_| {
+                            // (*) binder moved here
+                            ty::PredicateKind::Trait(ty::TraitPredicate {
+                                trait_ref,
+                                constness: predicate.constness,
+                            })
+                        })
+                        .to_predicate(infcx.tcx),
+                );
+                // Don't report overflow errors. Otherwise equivalent to may_hold.
+                if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) {
+                    if result.may_apply() {
+                        engine.relationships().entry(ty).or_default().self_in_trait = true;
+                    }
+                }
+            }
+        }
+    }
+
+    if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
+        // If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
+        // we need to make it into one.
+        if let Some(vid) = predicate.ty.ty_vid() {
+            debug!("relationship: {:?}.output = true", vid);
+            engine.relationships().entry(vid).or_default().output = true;
+        }
+    }
+}
index 3b6555de912e959465d14a13180ee4ed2ffdd9a7..9e1211336a4b01472026ee7a2cb0d53ecdfb3fac 100644 (file)
@@ -141,6 +141,7 @@ fn confirm_projection_candidate(
             let placeholder_trait_predicate =
                 self.infcx().replace_bound_vars_with_placeholders(trait_predicate);
             let placeholder_self_ty = placeholder_trait_predicate.self_ty();
+            let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
             let (def_id, substs) = match *placeholder_self_ty.kind() {
                 ty::Projection(proj) => (proj.item_def_id, proj.substs),
                 ty::Opaque(def_id, substs) => (def_id, substs),
@@ -164,7 +165,7 @@ fn confirm_projection_candidate(
             obligations.extend(self.infcx.commit_if_ok(|_| {
                 self.infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .sup(placeholder_trait_predicate.trait_ref.to_poly_trait_ref(), candidate.value)
+                    .sup(placeholder_trait_predicate.to_poly_trait_ref(), candidate.value)
                     .map(|InferOk { obligations, .. }| obligations)
                     .map_err(|_| Unimplemented)
             })?);
@@ -646,7 +647,7 @@ fn confirm_closure_candidate(
             obligations.push(Obligation::new(
                 obligation.cause.clone(),
                 obligation.param_env,
-                ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)
+                ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
                     .to_predicate(self.tcx()),
             ));
         }
@@ -898,10 +899,10 @@ fn confirm_builtin_unsize_candidate(
                 );
 
                 // We can only make objects from sized types.
-                let tr = ty::TraitRef::new(
+                let tr = ty::Binder::dummy(ty::TraitRef::new(
                     tcx.require_lang_item(LangItem::Sized, None),
                     tcx.mk_substs_trait(source, &[]),
-                );
+                ));
                 nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
 
                 // If the type is `Foo + 'a`, ensure that the type
index b966779500b617423162ad6f0104438a7e61a777..50d6f82ae18fa0a6e9654aecdcebdbf1be3da4d3 100644 (file)
@@ -314,6 +314,10 @@ pub fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
+    pub fn is_intercrate(&self) -> bool {
+        self.intercrate
+    }
+
     /// Returns `true` if the trait predicate is considerd `const` to this selection context.
     pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
         match pred.constness {
@@ -1197,6 +1201,13 @@ fn check_candidate_cache(
         param_env: ty::ParamEnv<'tcx>,
         cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
+        // Neither the global nor local cache is aware of intercrate
+        // mode, so don't do any caching. In particular, we might
+        // re-use the same `InferCtxt` with both an intercrate
+        // and non-intercrate `SelectionContext`
+        if self.intercrate {
+            return None;
+        }
         let tcx = self.tcx();
         let pred = &cache_fresh_trait_pred.skip_binder();
         let trait_ref = pred.trait_ref;
@@ -1233,6 +1244,13 @@ fn can_cache_candidate(
         &self,
         result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>,
     ) -> bool {
+        // Neither the global nor local cache is aware of intercrate
+        // mode, so don't do any caching. In particular, we might
+        // re-use the same `InferCtxt` with both an intercrate
+        // and non-intercrate `SelectionContext`
+        if self.intercrate {
+            return false;
+        }
         match result {
             Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.needs_infer(),
             _ => true,
index c8bcab6efd7ca4cac621368a8e59036b8a0c799a..ec7dcd4a419beb4e354fcc8e0d71ca95806c3e6f 100644 (file)
@@ -50,7 +50,7 @@ fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
             debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
-            self.nonblanket_impls.entry(st).or_default().push(impl_def_id)
+            self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
         } else {
             debug!("insert_blindly: impl_def_id={:?} st=None", impl_def_id);
             self.blanket_impls.push(impl_def_id)
@@ -65,7 +65,7 @@ fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let vec: &mut Vec<DefId>;
         if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
             debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
-            vec = self.nonblanket_impls.get_mut(&st).unwrap();
+            vec = self.non_blanket_impls.get_mut(&st).unwrap();
         } else {
             debug!("remove_existing: impl_def_id={:?} st=None", impl_def_id);
             vec = &mut self.blanket_impls;
@@ -104,19 +104,21 @@ fn insert(
                 let self_ty = trait_ref.self_ty();
 
                 // FIXME: should postpone string formatting until we decide to actually emit.
-                with_no_trimmed_paths(|| OverlapError {
-                    with_impl: possible_sibling,
-                    trait_desc: trait_ref.print_only_trait_path().to_string(),
-                    // Only report the `Self` type if it has at least
-                    // some outer concrete shell; otherwise, it's
-                    // not adding much information.
-                    self_desc: if self_ty.has_concrete_skeleton() {
-                        Some(self_ty.to_string())
-                    } else {
-                        None
-                    },
-                    intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
-                    involves_placeholder: overlap.involves_placeholder,
+                with_no_trimmed_paths(|| {
+                    OverlapError {
+                        with_impl: possible_sibling,
+                        trait_desc: trait_ref.print_only_trait_path().to_string(),
+                        // Only report the `Self` type if it has at least
+                        // some outer concrete shell; otherwise, it's
+                        // not adding much information.
+                        self_desc: if self_ty.has_concrete_skeleton() {
+                            Some(self_ty.to_string())
+                        } else {
+                            None
+                        },
+                        intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
+                        involves_placeholder: overlap.involves_placeholder,
+                    }
                 })
             };
 
@@ -216,7 +218,7 @@ fn insert(
 }
 
 fn iter_children(children: &mut Children) -> impl Iterator<Item = DefId> + '_ {
-    let nonblanket = children.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter());
+    let nonblanket = children.non_blanket_impls.iter().flat_map(|(_, v)| v.iter());
     children.blanket_impls.iter().chain(nonblanket).cloned()
 }
 
@@ -224,7 +226,7 @@ fn filtered_children(
     children: &mut Children,
     st: SimplifiedType,
 ) -> impl Iterator<Item = DefId> + '_ {
-    let nonblanket = children.nonblanket_impls.entry(st).or_default().iter();
+    let nonblanket = children.non_blanket_impls.entry(st).or_default().iter();
     children.blanket_impls.iter().chain(nonblanket).cloned()
 }
 
index b108d85bb20c9afc2184fab8be73133fc8d05289..ed49abbbedc92dfe8415a16f377c45f0c84ba567 100644 (file)
@@ -248,7 +248,7 @@ pub fn predicate_for_trait_ref<'tcx>(
         cause,
         param_env,
         recursion_depth,
-        predicate: trait_ref.without_const().to_predicate(tcx),
+        predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
     }
 }
 
index 75307f135636be8f9be8f425e12f9a4b6c30207e..cb47ba9c360da14401081cfc132e70e61a678641 100644 (file)
@@ -209,7 +209,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
         _ => return,
     };
     let fix_span =
-        |impl_item_ref: &hir::ImplItemRef<'_>| match tcx.hir().impl_item(impl_item_ref.id).kind {
+        |impl_item_ref: &hir::ImplItemRef| match tcx.hir().impl_item(impl_item_ref.id).kind {
             hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::TyAlias(ty) => ty.span,
             _ => impl_item_ref.span,
         };
@@ -349,7 +349,7 @@ fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elabo
                         new_cause,
                         depth,
                         param_env,
-                        ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
+                        ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
                     )
                 }),
         );
@@ -399,7 +399,7 @@ fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) {
                         cause.clone(),
                         depth,
                         param_env,
-                        ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
+                        ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
                     )
                 }),
         );
@@ -416,7 +416,7 @@ fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<
                 cause,
                 self.recursion_depth,
                 self.param_env,
-                trait_ref.without_const().to_predicate(self.infcx.tcx),
+                ty::Binder::dummy(trait_ref).without_const().to_predicate(self.infcx.tcx),
             ));
         }
     }
@@ -443,9 +443,9 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                             let obligations = self.nominal_obligations(uv.def.did, substs);
                             self.out.extend(obligations);
 
-                            let predicate = ty::PredicateKind::ConstEvaluatable(
+                            let predicate = ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
                                 ty::Unevaluated::new(uv.def, substs),
-                            )
+                            ))
                             .to_predicate(self.tcx());
                             let cause = self.cause(traits::MiscObligation);
                             self.out.push(traits::Obligation::with_depth(
@@ -469,8 +469,10 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                                     cause,
                                     self.recursion_depth,
                                     self.param_env,
-                                    ty::PredicateKind::WellFormed(resolved_constant.into())
-                                        .to_predicate(self.tcx()),
+                                    ty::Binder::dummy(ty::PredicateKind::WellFormed(
+                                        resolved_constant.into(),
+                                    ))
+                                    .to_predicate(self.tcx()),
                                 ));
                             }
                         }
@@ -556,8 +558,10 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                             cause,
                             depth,
                             param_env,
-                            ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(rty, r))
-                                .to_predicate(self.tcx()),
+                            ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
+                                ty::OutlivesPredicate(rty, r),
+                            ))
+                            .to_predicate(self.tcx()),
                         ));
                     }
                 }
@@ -646,7 +650,8 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                                 cause.clone(),
                                 depth,
                                 param_env,
-                                ty::PredicateKind::ObjectSafe(did).to_predicate(tcx),
+                                ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did))
+                                    .to_predicate(tcx),
                             )
                         }));
                     }
@@ -673,7 +678,8 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
                             cause,
                             self.recursion_depth,
                             param_env,
-                            ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
+                            ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))
+                                .to_predicate(self.tcx()),
                         ));
                     } else {
                         // Yes, resolved, proceed with the result.
index 219165ff5503555b46e09d3ffab19731e5ec91ef..2e56a1bf6839e708d1ee90917c6fb73cf78be1db 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_traits"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 tracing = "0.1"
index a76fb842616152af6da34f435c8a1b6a4dd69073..f954cab240ca20db69d31a7f38a8c328db404583 100644 (file)
@@ -156,7 +156,8 @@ fn relate_mir_and_user_ty(
             self.relate(self_ty, Variance::Invariant, impl_self_ty)?;
 
             self.prove_predicate(
-                ty::PredicateKind::WellFormed(impl_self_ty.into()).to_predicate(self.tcx()),
+                ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
+                    .to_predicate(self.tcx()),
                 span,
             );
         }
@@ -173,7 +174,7 @@ fn relate_mir_and_user_ty(
         // type were ill-formed but did not appear in `ty`,
         // which...could happen with normalization...
         self.prove_predicate(
-            ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
+            ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()),
             span,
         );
         Ok(())
index 2eb27fb1ad67e66c02800b8d342926c4c02c6dd5..78df95e680e005fd7fcc7c0d626f153b1dda6517 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_ty_utils"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 tracing = "0.1"
index 27ad7bf4c2d46eae363666ac330ed315791fcfb0..3d3b2743700917090e208f651426d5b3d5d3e79a 100644 (file)
@@ -100,7 +100,7 @@ fn associated_item_from_trait_item_ref(
 fn associated_item_from_impl_item_ref(
     tcx: TyCtxt<'_>,
     parent_def_id: LocalDefId,
-    impl_item_ref: &hir::ImplItemRef<'_>,
+    impl_item_ref: &hir::ImplItemRef,
 ) -> ty::AssocItem {
     let def_id = impl_item_ref.id.def_id;
     let (kind, has_self) = match impl_item_ref.kind {
index 1f6acbe0d811da4bb047434b205c4b17d9aca38a..439e6cdf70698945a183501613650e651a60454b 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_type_ir"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 doctest = false
index dd76a5e4b99b235b0ba395fa38e95776b3029f3e..7e570e151c5298c6431481097493273a823bdcbc 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustc_typeck"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 test = false
index 2f2223ee822e4f0f8ea480bfa988beb4bba7889d..33df541eb2ba88ccb19303722bf0193f7e04edca 100644 (file)
@@ -2417,13 +2417,14 @@ fn impl_trait_ty_to_ty(
         let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
             if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
                 // Our own parameters are the resolved lifetimes.
-                match param.kind {
-                    GenericParamDefKind::Lifetime
-                        if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] =>
-                    {
+                if let GenericParamDefKind::Lifetime = param.kind {
+                    if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] {
                         self.ast_region_to_region(lifetime, None).into()
+                    } else {
+                        bug!()
                     }
-                    _ => bug!(),
+                } else {
+                    bug!()
                 }
             } else {
                 match param.kind {
index 01227cad334fc783e12d0f79ef97b63a5150ae32..6a231e719e66462a9751bd69392442e3648a124a 100644 (file)
@@ -524,13 +524,14 @@ pub(crate) fn opt_suggest_box_span(
                 for o in obligations {
                     match o.predicate.kind().skip_binder() {
                         ty::PredicateKind::Trait(t) => {
-                            let pred = ty::PredicateKind::Trait(ty::TraitPredicate {
-                                trait_ref: ty::TraitRef {
-                                    def_id: t.def_id(),
-                                    substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
-                                },
-                                constness: t.constness,
-                            });
+                            let pred =
+                                ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
+                                    trait_ref: ty::TraitRef {
+                                        def_id: t.def_id(),
+                                        substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
+                                    },
+                                    constness: t.constness,
+                                }));
                             let obl = Obligation::new(
                                 o.cause.clone(),
                                 self.param_env,
index 1cc06b8c2e544b9ca5bdf2130cd61ea1dd21b46f..e007d971bb072bd1ae109b0c70fca6803e4915b6 100644 (file)
@@ -246,12 +246,18 @@ fn try_overloaded_call_traits(
                 if borrow {
                     // Check for &self vs &mut self in the method signature. Since this is either
                     // the Fn or FnMut trait, it should be one of those.
-                    let (region, mutbl) =
-                        if let ty::Ref(r, _, mutbl) = method.sig.inputs()[0].kind() {
-                            (r, mutbl)
-                        } else {
-                            span_bug!(call_expr.span, "input to call/call_mut is not a ref?");
-                        };
+                    let (region, mutbl) = if let ty::Ref(r, _, mutbl) =
+                        method.sig.inputs()[0].kind()
+                    {
+                        (r, mutbl)
+                    } else {
+                        // The `fn`/`fn_mut` lang item is ill-formed, which should have
+                        // caused an error elsewhere.
+                        self.tcx
+                            .sess
+                            .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref?");
+                        return None;
+                    };
 
                     let mutbl = match mutbl {
                         hir::Mutability::Not => AutoBorrowMutability::Not,
index 54e4eb4768813525816aa21ea9957e433201bf98..9f0ed0cd18d920aeeb125d9f5bcd4ed3902cdd21 100644 (file)
@@ -241,32 +241,16 @@ pub(super) fn check_fn<'a, 'tcx>(
     // we saw and assigning it to the expected return type. This isn't
     // really expected to fail, since the coercions would have failed
     // earlier when trying to find a LUB.
-    //
-    // However, the behavior around `!` is sort of complex. In the
-    // event that the `actual_return_ty` comes back as `!`, that
-    // indicates that the fn either does not return or "returns" only
-    // values of type `!`. In this case, if there is an expected
-    // return type that is *not* `!`, that should be ok. But if the
-    // return type is being inferred, we want to "fallback" to `!`:
-    //
-    //     let x = move || panic!();
-    //
-    // To allow for that, I am creating a type variable with diverging
-    // fallback. This was deemed ever so slightly better than unifying
-    // the return value with `!` because it allows for the caller to
-    // make more assumptions about the return type (e.g., they could do
-    //
-    //     let y: Option<u32> = Some(x());
-    //
-    // which would then cause this return type to become `u32`, not
-    // `!`).
     let coercion = fcx.ret_coercion.take().unwrap().into_inner();
     let mut actual_return_ty = coercion.complete(&fcx);
-    if actual_return_ty.is_never() {
-        actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::DivergingFn,
-            span,
-        });
+    debug!("actual_return_ty = {:?}", actual_return_ty);
+    if let ty::Dynamic(..) = declared_ret_ty.kind() {
+        // We have special-cased the case where the function is declared
+        // `-> dyn Foo` and we don't actually relate it to the
+        // `fcx.ret_coercion`, so just substitute a type variable.
+        actual_return_ty =
+            fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
+        debug!("actual_return_ty replaced with {:?}", actual_return_ty);
     }
     fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
 
@@ -906,7 +890,7 @@ pub(super) fn check_impl_items_against_trait<'tcx>(
     full_impl_span: Span,
     impl_id: LocalDefId,
     impl_trait_ref: ty::TraitRef<'tcx>,
-    impl_item_refs: &[hir::ImplItemRef<'_>],
+    impl_item_refs: &[hir::ImplItemRef],
 ) {
     // If the trait reference itself is erroneous (so the compilation is going
     // to fail), skip checking the items here -- the `impl_item` table in `tcx`
index 92d0470bc2f58ceb92550ad72a12130192b8bb1b..ef18c1e7779d862a4a9710eb6cb1c80a98bb02b1 100644 (file)
@@ -159,24 +159,7 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
 
         // Coercing from `!` to any type is allowed:
         if a.is_never() {
-            // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
-            // type variable, we want `?T` to fallback to `!` if not
-            // otherwise constrained. An example where this arises:
-            //
-            //     let _: Option<?T> = Some({ return; });
-            //
-            // here, we would coerce from `!` to `?T`.
-            return if b.is_ty_var() {
-                // Micro-optimization: no need for this if `b` is
-                // already resolved in some way.
-                let diverging_ty = self.next_diverging_ty_var(TypeVariableOrigin {
-                    kind: TypeVariableOriginKind::AdjustmentType,
-                    span: self.cause.span,
-                });
-                self.coerce_from_inference_variable(diverging_ty, b, simple(Adjust::NeverToAny))
-            } else {
-                success(simple(Adjust::NeverToAny)(b), b, vec![])
-            };
+            return success(simple(Adjust::NeverToAny)(b), b, vec![]);
         }
 
         // Coercing *from* an unresolved inference variable means that
@@ -273,10 +256,10 @@ fn coerce_from_inference_variable(
                     obligations.push(Obligation::new(
                         self.cause.clone(),
                         self.param_env,
-                        ty::PredicateKind::Coerce(ty::CoercePredicate {
+                        ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate {
                             a: source_ty,
                             b: target_ty,
-                        })
+                        }))
                         .to_predicate(self.tcx()),
                     ));
                 }
index 11b6c93a115283c8af05c75db1252ee916d427e0..8a69e0a737d501c1b2aed4d780c1a65fd8b321da 100644 (file)
@@ -77,7 +77,7 @@ fn check_expr_meets_expectation_or_error(
                 !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id),
                 "expression with never type wound up being adjusted"
             );
-            let adj_ty = self.next_diverging_ty_var(TypeVariableOrigin {
+            let adj_ty = self.next_ty_var(TypeVariableOrigin {
                 kind: TypeVariableOriginKind::AdjustmentType,
                 span: expr.span,
             });
index 8f6cdc7bb12a7243ab97820e956a4e185c43330d..296e45337ed1035b3ed1868396f371ba6b045c86 100644 (file)
@@ -1,29 +1,52 @@
 use crate::check::FnCtxt;
-use rustc_infer::infer::type_variable::Diverging;
+use rustc_data_structures::{
+    fx::FxHashMap,
+    graph::WithSuccessors,
+    graph::{iterate::DepthFirstSearch, vec_graph::VecGraph},
+    stable_set::FxHashSet,
+};
 use rustc_middle::ty::{self, Ty};
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
     /// Performs type inference fallback, returning true if any fallback
     /// occurs.
     pub(super) fn type_inference_fallback(&self) -> bool {
+        debug!(
+            "type-inference-fallback start obligations: {:#?}",
+            self.fulfillment_cx.borrow_mut().pending_obligations()
+        );
+
         // All type checking constraints were added, try to fallback unsolved variables.
         self.select_obligations_where_possible(false, |_| {});
-        let mut fallback_has_occurred = false;
 
+        debug!(
+            "type-inference-fallback post selection obligations: {:#?}",
+            self.fulfillment_cx.borrow_mut().pending_obligations()
+        );
+
+        // Check if we have any unsolved varibales. If not, no need for fallback.
+        let unsolved_variables = self.unsolved_variables();
+        if unsolved_variables.is_empty() {
+            return false;
+        }
+
+        let diverging_fallback = self.calculate_diverging_fallback(&unsolved_variables);
+
+        let mut fallback_has_occurred = false;
         // We do fallback in two passes, to try to generate
         // better error messages.
         // The first time, we do *not* replace opaque types.
-        for ty in &self.unsolved_variables() {
+        for ty in unsolved_variables {
             debug!("unsolved_variable = {:?}", ty);
-            fallback_has_occurred |= self.fallback_if_possible(ty);
+            fallback_has_occurred |= self.fallback_if_possible(ty, &diverging_fallback);
         }
 
-        // We now see if we can make progress. This might
-        // cause us to unify inference variables for opaque types,
-        // since we may have unified some other type variables
-        // during the first phase of fallback.
-        // This means that we only replace inference variables with their underlying
-        // opaque types as a last resort.
+        // We now see if we can make progress. This might cause us to
+        // unify inference variables for opaque types, since we may
+        // have unified some other type variables during the first
+        // phase of fallback.  This means that we only replace
+        // inference variables with their underlying opaque types as a
+        // last resort.
         //
         // In code like this:
         //
@@ -62,36 +85,44 @@ pub(super) fn type_inference_fallback(&self) -> bool {
     //
     // - Unconstrained floats are replaced with with `f64`.
     //
-    // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
-    //   is enabled. Otherwise, they are replaced with `()`.
+    // - Non-numerics may get replaced with `()` or `!`, depending on
+    //   how they were categorized by `calculate_diverging_fallback`
+    //   (and the setting of `#![feature(never_type_fallback)]`).
+    //
+    // Fallback becomes very dubious if we have encountered
+    // type-checking errors.  In that case, fallback to Error.
     //
-    // Fallback becomes very dubious if we have encountered type-checking errors.
-    // In that case, fallback to Error.
     // The return value indicates whether fallback has occurred.
-    fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
+    fn fallback_if_possible(
+        &self,
+        ty: Ty<'tcx>,
+        diverging_fallback: &FxHashMap<Ty<'tcx>, Ty<'tcx>>,
+    ) -> bool {
         // Careful: we do NOT shallow-resolve `ty`. We know that `ty`
-        // is an unsolved variable, and we determine its fallback based
-        // solely on how it was created, not what other type variables
-        // it may have been unified with since then.
+        // is an unsolved variable, and we determine its fallback
+        // based solely on how it was created, not what other type
+        // variables it may have been unified with since then.
         //
-        // The reason this matters is that other attempts at fallback may
-        // (in principle) conflict with this fallback, and we wish to generate
-        // a type error in that case. (However, this actually isn't true right now,
-        // because we're only using the builtin fallback rules. This would be
-        // true if we were using user-supplied fallbacks. But it's still useful
-        // to write the code to detect bugs.)
+        // The reason this matters is that other attempts at fallback
+        // may (in principle) conflict with this fallback, and we wish
+        // to generate a type error in that case. (However, this
+        // actually isn't true right now, because we're only using the
+        // builtin fallback rules. This would be true if we were using
+        // user-supplied fallbacks. But it's still useful to write the
+        // code to detect bugs.)
         //
-        // (Note though that if we have a general type variable `?T` that is then unified
-        // with an integer type variable `?I` that ultimately never gets
-        // resolved to a special integral type, `?T` is not considered unsolved,
-        // but `?I` is. The same is true for float variables.)
+        // (Note though that if we have a general type variable `?T`
+        // that is then unified with an integer type variable `?I`
+        // that ultimately never gets resolved to a special integral
+        // type, `?T` is not considered unsolved, but `?I` is. The
+        // same is true for float variables.)
         let fallback = match ty.kind() {
             _ if self.is_tainted_by_errors() => self.tcx.ty_error(),
             ty::Infer(ty::IntVar(_)) => self.tcx.types.i32,
             ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
-            _ => match self.type_var_diverges(ty) {
-                Diverging::Diverges => self.tcx.mk_diverging_default(),
-                Diverging::NotDiverging => return false,
+            _ => match diverging_fallback.get(&ty) {
+                Some(&fallback_ty) => fallback_ty,
+                None => return false,
             },
         };
         debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback);
@@ -105,11 +136,10 @@ fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
         true
     }
 
-    /// Second round of fallback: Unconstrained type variables
-    /// created from the instantiation of an opaque
-    /// type fall back to the opaque type itself. This is a
-    /// somewhat incomplete attempt to manage "identity passthrough"
-    /// for `impl Trait` types.
+    /// Second round of fallback: Unconstrained type variables created
+    /// from the instantiation of an opaque type fall back to the
+    /// opaque type itself. This is a somewhat incomplete attempt to
+    /// manage "identity passthrough" for `impl Trait` types.
     ///
     /// For example, in this code:
     ///
@@ -158,4 +188,274 @@ fn fallback_opaque_type_vars(&self, ty: Ty<'tcx>) -> bool {
             return false;
         }
     }
+
+    /// The "diverging fallback" system is rather complicated. This is
+    /// a result of our need to balance 'do the right thing' with
+    /// backwards compatibility.
+    ///
+    /// "Diverging" type variables are variables created when we
+    /// coerce a `!` type into an unbound type variable `?X`. If they
+    /// never wind up being constrained, the "right and natural" thing
+    /// is that `?X` should "fallback" to `!`. This means that e.g. an
+    /// expression like `Some(return)` will ultimately wind up with a
+    /// type like `Option<!>` (presuming it is not assigned or
+    /// constrained to have some other type).
+    ///
+    /// However, the fallback used to be `()` (before the `!` type was
+    /// added).  Moreover, there are cases where the `!` type 'leaks
+    /// out' from dead code into type variables that affect live
+    /// code. The most common case is something like this:
+    ///
+    /// ```rust
+    /// match foo() {
+    ///     22 => Default::default(), // call this type `?D`
+    ///     _ => return, // return has type `!`
+    /// } // call the type of this match `?M`
+    /// ```
+    ///
+    /// Here, coercing the type `!` into `?M` will create a diverging
+    /// type variable `?X` where `?X <: ?M`.  We also have that `?D <:
+    /// ?M`. If `?M` winds up unconstrained, then `?X` will
+    /// fallback. If it falls back to `!`, then all the type variables
+    /// will wind up equal to `!` -- this includes the type `?D`
+    /// (since `!` doesn't implement `Default`, we wind up a "trait
+    /// not implemented" error in code like this). But since the
+    /// original fallback was `()`, this code used to compile with `?D
+    /// = ()`. This is somewhat surprising, since `Default::default()`
+    /// on its own would give an error because the types are
+    /// insufficiently constrained.
+    ///
+    /// Our solution to this dilemma is to modify diverging variables
+    /// so that they can *either* fallback to `!` (the default) or to
+    /// `()` (the backwards compatibility case). We decide which
+    /// fallback to use based on whether there is a coercion pattern
+    /// like this:
+    ///
+    /// ```
+    /// ?Diverging -> ?V
+    /// ?NonDiverging -> ?V
+    /// ?V != ?NonDiverging
+    /// ```
+    ///
+    /// Here `?Diverging` represents some diverging type variable and
+    /// `?NonDiverging` represents some non-diverging type
+    /// variable. `?V` can be any type variable (diverging or not), so
+    /// long as it is not equal to `?NonDiverging`.
+    ///
+    /// Intuitively, what we are looking for is a case where a
+    /// "non-diverging" type variable (like `?M` in our example above)
+    /// is coerced *into* some variable `?V` that would otherwise
+    /// fallback to `!`. In that case, we make `?V` fallback to `!`,
+    /// along with anything that would flow into `?V`.
+    ///
+    /// The algorithm we use:
+    /// * Identify all variables that are coerced *into* by a
+    ///   diverging variable.  Do this by iterating over each
+    ///   diverging, unsolved variable and finding all variables
+    ///   reachable from there. Call that set `D`.
+    /// * Walk over all unsolved, non-diverging variables, and find
+    ///   any variable that has an edge into `D`.
+    fn calculate_diverging_fallback(
+        &self,
+        unsolved_variables: &[Ty<'tcx>],
+    ) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
+        debug!("calculate_diverging_fallback({:?})", unsolved_variables);
+
+        let relationships = self.fulfillment_cx.borrow_mut().relationships().clone();
+
+        // Construct a coercion graph where an edge `A -> B` indicates
+        // a type variable is that is coerced
+        let coercion_graph = self.create_coercion_graph();
+
+        // Extract the unsolved type inference variable vids; note that some
+        // unsolved variables are integer/float variables and are excluded.
+        let unsolved_vids = unsolved_variables.iter().filter_map(|ty| ty.ty_vid());
+
+        // Compute the diverging root vids D -- that is, the root vid of
+        // those type variables that (a) are the target of a coercion from
+        // a `!` type and (b) have not yet been solved.
+        //
+        // These variables are the ones that are targets for fallback to
+        // either `!` or `()`.
+        let diverging_roots: FxHashSet<ty::TyVid> = self
+            .diverging_type_vars
+            .borrow()
+            .iter()
+            .map(|&ty| self.infcx.shallow_resolve(ty))
+            .filter_map(|ty| ty.ty_vid())
+            .map(|vid| self.infcx.root_var(vid))
+            .collect();
+        debug!(
+            "calculate_diverging_fallback: diverging_type_vars={:?}",
+            self.diverging_type_vars.borrow()
+        );
+        debug!("calculate_diverging_fallback: diverging_roots={:?}", diverging_roots);
+
+        // Find all type variables that are reachable from a diverging
+        // type variable. These will typically default to `!`, unless
+        // we find later that they are *also* reachable from some
+        // other type variable outside this set.
+        let mut roots_reachable_from_diverging = DepthFirstSearch::new(&coercion_graph);
+        let mut diverging_vids = vec![];
+        let mut non_diverging_vids = vec![];
+        for unsolved_vid in unsolved_vids {
+            let root_vid = self.infcx.root_var(unsolved_vid);
+            debug!(
+                "calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}",
+                unsolved_vid,
+                root_vid,
+                diverging_roots.contains(&root_vid),
+            );
+            if diverging_roots.contains(&root_vid) {
+                diverging_vids.push(unsolved_vid);
+                roots_reachable_from_diverging.push_start_node(root_vid);
+
+                debug!(
+                    "calculate_diverging_fallback: root_vid={:?} reaches {:?}",
+                    root_vid,
+                    coercion_graph.depth_first_search(root_vid).collect::<Vec<_>>()
+                );
+
+                // drain the iterator to visit all nodes reachable from this node
+                roots_reachable_from_diverging.complete_search();
+            } else {
+                non_diverging_vids.push(unsolved_vid);
+            }
+        }
+
+        debug!(
+            "calculate_diverging_fallback: roots_reachable_from_diverging={:?}",
+            roots_reachable_from_diverging,
+        );
+
+        // Find all type variables N0 that are not reachable from a
+        // diverging variable, and then compute the set reachable from
+        // N0, which we call N. These are the *non-diverging* type
+        // variables. (Note that this set consists of "root variables".)
+        let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
+        for &non_diverging_vid in &non_diverging_vids {
+            let root_vid = self.infcx.root_var(non_diverging_vid);
+            if roots_reachable_from_diverging.visited(root_vid) {
+                continue;
+            }
+            roots_reachable_from_non_diverging.push_start_node(root_vid);
+            roots_reachable_from_non_diverging.complete_search();
+        }
+        debug!(
+            "calculate_diverging_fallback: roots_reachable_from_non_diverging={:?}",
+            roots_reachable_from_non_diverging,
+        );
+
+        debug!("inherited: {:#?}", self.inh.fulfillment_cx.borrow_mut().pending_obligations());
+        debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
+        debug!("relationships: {:#?}", relationships);
+
+        // For each diverging variable, figure out whether it can
+        // reach a member of N. If so, it falls back to `()`. Else
+        // `!`.
+        let mut diverging_fallback = FxHashMap::default();
+        diverging_fallback.reserve(diverging_vids.len());
+        for &diverging_vid in &diverging_vids {
+            let diverging_ty = self.tcx.mk_ty_var(diverging_vid);
+            let root_vid = self.infcx.root_var(diverging_vid);
+            let can_reach_non_diverging = coercion_graph
+                .depth_first_search(root_vid)
+                .any(|n| roots_reachable_from_non_diverging.visited(n));
+
+            let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
+
+            for (vid, rel) in relationships.iter() {
+                if self.infcx.root_var(*vid) == root_vid {
+                    relationship.self_in_trait |= rel.self_in_trait;
+                    relationship.output |= rel.output;
+                }
+            }
+
+            if relationship.self_in_trait && relationship.output {
+                // This case falls back to () to ensure that the code pattern in
+                // src/test/ui/never_type/fallback-closure-ret.rs continues to
+                // compile when never_type_fallback is enabled.
+                //
+                // This rule is not readily explainable from first principles,
+                // but is rather intended as a patchwork fix to ensure code
+                // which compiles before the stabilization of never type
+                // fallback continues to work.
+                //
+                // Typically this pattern is encountered in a function taking a
+                // closure as a parameter, where the return type of that closure
+                // (checked by `relationship.output`) is expected to implement
+                // some trait (checked by `relationship.self_in_trait`). This
+                // can come up in non-closure cases too, so we do not limit this
+                // rule to specifically `FnOnce`.
+                //
+                // When the closure's body is something like `panic!()`, the
+                // return type would normally be inferred to `!`. However, it
+                // needs to fall back to `()` in order to still compile, as the
+                // trait is specifically implemented for `()` but not `!`.
+                //
+                // For details on the requirements for these relationships to be
+                // set, see the relationship finding module in
+                // compiler/rustc_trait_selection/src/traits/relationships.rs.
+                debug!("fallback to () - found trait and projection: {:?}", diverging_vid);
+                diverging_fallback.insert(diverging_ty, self.tcx.types.unit);
+            } else if can_reach_non_diverging {
+                debug!("fallback to () - reached non-diverging: {:?}", diverging_vid);
+                diverging_fallback.insert(diverging_ty, self.tcx.types.unit);
+            } else {
+                debug!("fallback to ! - all diverging: {:?}", diverging_vid);
+                diverging_fallback.insert(diverging_ty, self.tcx.mk_diverging_default());
+            }
+        }
+
+        diverging_fallback
+    }
+
+    /// Returns a graph whose nodes are (unresolved) inference variables and where
+    /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`.
+    fn create_coercion_graph(&self) -> VecGraph<ty::TyVid> {
+        let pending_obligations = self.fulfillment_cx.borrow_mut().pending_obligations();
+        debug!("create_coercion_graph: pending_obligations={:?}", pending_obligations);
+        let coercion_edges: Vec<(ty::TyVid, ty::TyVid)> = pending_obligations
+            .into_iter()
+            .filter_map(|obligation| {
+                // The predicates we are looking for look like `Coerce(?A -> ?B)`.
+                // They will have no bound variables.
+                obligation.predicate.kind().no_bound_vars()
+            })
+            .filter_map(|atom| {
+                // We consider both subtyping and coercion to imply 'flow' from
+                // some position in the code `a` to a different position `b`.
+                // This is then used to determine which variables interact with
+                // live code, and as such must fall back to `()` to preserve
+                // soundness.
+                //
+                // In practice currently the two ways that this happens is
+                // coercion and subtyping.
+                let (a, b) = if let ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) = atom {
+                    (a, b)
+                } else if let ty::PredicateKind::Subtype(ty::SubtypePredicate {
+                    a_is_expected: _,
+                    a,
+                    b,
+                }) = atom
+                {
+                    (a, b)
+                } else {
+                    return None;
+                };
+
+                let a_vid = self.root_vid(a)?;
+                let b_vid = self.root_vid(b)?;
+                Some((a_vid, b_vid))
+            })
+            .collect();
+        debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges);
+        let num_ty_vars = self.infcx.num_ty_vars();
+        VecGraph::new(num_ty_vars, coercion_edges)
+    }
+
+    /// If `ty` is an unresolved type variable, returns its root vid.
+    fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
+        Some(self.infcx.root_var(self.infcx.shallow_resolve(ty).ty_vid()?))
+    }
 }
index ed01dae59f6723e1460d2a534c8c34faac305813..553f5ed8a0ca4f358cf9c59e1b7241137652dd0b 100644 (file)
@@ -286,6 +286,15 @@ pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>
             return;
         }
 
+        for a in &adj {
+            if let Adjust::NeverToAny = a.kind {
+                if a.target.is_ty_var() {
+                    self.diverging_type_vars.borrow_mut().insert(a.target);
+                    debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target);
+                }
+            }
+        }
+
         let autoborrow_mut = adj.iter().any(|adj| {
             matches!(
                 adj,
@@ -576,7 +585,7 @@ pub fn register_wf_obligation(
         self.register_predicate(traits::Obligation::new(
             cause,
             self.param_env,
-            ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
+            ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx),
         ));
     }
 
index 0acf1d26e257d9d5b88d1544e938f73b6d0d366d..da8b863e2dbe6f17e7530151247568061e25aa61 100644 (file)
@@ -484,8 +484,9 @@ pub(in super::super) fn suggest_missing_return_type(
                 debug!("suggest_missing_return_type: return type {:?}", ty);
                 debug!("suggest_missing_return_type: expected type {:?}", ty);
                 let bound_vars = self.tcx.late_bound_vars(fn_id);
-                let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
+                let ty = Binder::bind_with_vars(ty, bound_vars);
                 let ty = self.normalize_associated_types_in(sp, ty);
+                let ty = self.tcx.erase_late_bound_regions(ty);
                 if self.can_coerce(expected, ty) {
                     err.span_label(sp, format!("expected `{}` because of return type", expected));
                     return true;
index 3da9fd159a728e7e909e89980ee476041050eef1..2910ce6de689965c4adcde2668aedab785443790 100644 (file)
@@ -5,6 +5,7 @@
 
 use super::FnCtxt;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
+use rustc_errors::pluralize;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
 use rustc_middle::middle::region::{self, YieldData};
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::symbol::sym;
 use rustc_span::Span;
 use smallvec::SmallVec;
+use tracing::debug;
 
 struct InteriorVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -30,12 +33,14 @@ struct InteriorVisitor<'a, 'tcx> {
     /// that they may succeed the said yield point in the post-order.
     guard_bindings: SmallVec<[SmallVec<[HirId; 4]>; 1]>,
     guard_bindings_set: HirIdSet,
+    linted_values: HirIdSet,
 }
 
 impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
     fn record(
         &mut self,
         ty: Ty<'tcx>,
+        hir_id: HirId,
         scope: Option<region::Scope>,
         expr: Option<&'tcx Expr<'tcx>>,
         source_span: Span,
@@ -117,6 +122,23 @@ fn record(
             } else {
                 // Insert the type into the ordered set.
                 let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree));
+
+                if !self.linted_values.contains(&hir_id) {
+                    check_must_not_suspend_ty(
+                        self.fcx,
+                        ty,
+                        hir_id,
+                        SuspendCheckData {
+                            expr,
+                            source_span,
+                            yield_span: yield_data.span,
+                            plural_len: 1,
+                            ..Default::default()
+                        },
+                    );
+                    self.linted_values.insert(hir_id);
+                }
+
                 self.types.insert(ty::GeneratorInteriorTypeCause {
                     span: source_span,
                     ty: &ty,
@@ -163,6 +185,7 @@ pub fn resolve_interior<'a, 'tcx>(
         prev_unresolved_span: None,
         guard_bindings: <_>::default(),
         guard_bindings_set: <_>::default(),
+        linted_values: <_>::default(),
     };
     intravisit::walk_body(&mut visitor, body);
 
@@ -290,7 +313,7 @@ fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
         if let PatKind::Binding(..) = pat.kind {
             let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
             let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
-            self.record(ty, Some(scope), None, pat.span, false);
+            self.record(ty, pat.hir_id, Some(scope), None, pat.span, false);
         }
     }
 
@@ -342,7 +365,14 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         // If there are adjustments, then record the final type --
         // this is the actual value that is being produced.
         if let Some(adjusted_ty) = self.fcx.typeck_results.borrow().expr_ty_adjusted_opt(expr) {
-            self.record(adjusted_ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern);
+            self.record(
+                adjusted_ty,
+                expr.hir_id,
+                scope,
+                Some(expr),
+                expr.span,
+                guard_borrowing_from_pattern,
+            );
         }
 
         // Also record the unadjusted type (which is the only type if
@@ -380,9 +410,23 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
                     tcx.mk_region(ty::RegionKind::ReErased),
                     ty::TypeAndMut { ty, mutbl: hir::Mutability::Not },
                 );
-                self.record(ref_ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern);
+                self.record(
+                    ref_ty,
+                    expr.hir_id,
+                    scope,
+                    Some(expr),
+                    expr.span,
+                    guard_borrowing_from_pattern,
+                );
             }
-            self.record(ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern);
+            self.record(
+                ty,
+                expr.hir_id,
+                scope,
+                Some(expr),
+                expr.span,
+                guard_borrowing_from_pattern,
+            );
         } else {
             self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
         }
@@ -409,3 +453,173 @@ fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
         }
     }
 }
+
+#[derive(Default)]
+pub struct SuspendCheckData<'a, 'tcx> {
+    expr: Option<&'tcx Expr<'tcx>>,
+    source_span: Span,
+    yield_span: Span,
+    descr_pre: &'a str,
+    descr_post: &'a str,
+    plural_len: usize,
+}
+
+// Returns whether it emitted a diagnostic or not
+// Note that this fn and the proceding one are based on the code
+// for creating must_use diagnostics
+//
+// Note that this technique was chosen over things like a `Suspend` marker trait
+// as it is simpler and has precendent in the compiler
+pub fn check_must_not_suspend_ty<'tcx>(
+    fcx: &FnCtxt<'_, 'tcx>,
+    ty: Ty<'tcx>,
+    hir_id: HirId,
+    data: SuspendCheckData<'_, 'tcx>,
+) -> bool {
+    if ty.is_unit()
+    // FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
+    // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
+    // `must_use`
+    // || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
+    {
+        return false;
+    }
+
+    let plural_suffix = pluralize!(data.plural_len);
+
+    match *ty.kind() {
+        ty::Adt(..) if ty.is_box() => {
+            let boxed_ty = ty.boxed_ty();
+            let descr_pre = &format!("{}boxed ", data.descr_pre);
+            check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
+        }
+        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did, hir_id, data),
+        // FIXME: support adding the attribute to TAITs
+        ty::Opaque(def, _) => {
+            let mut has_emitted = false;
+            for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) {
+                // We only look at the `DefId`, so it is safe to skip the binder here.
+                if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
+                    predicate.kind().skip_binder()
+                {
+                    let def_id = poly_trait_predicate.trait_ref.def_id;
+                    let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix);
+                    if check_must_not_suspend_def(
+                        fcx.tcx,
+                        def_id,
+                        hir_id,
+                        SuspendCheckData { descr_pre, ..data },
+                    ) {
+                        has_emitted = true;
+                        break;
+                    }
+                }
+            }
+            has_emitted
+        }
+        ty::Dynamic(binder, _) => {
+            let mut has_emitted = false;
+            for predicate in binder.iter() {
+                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
+                    let def_id = trait_ref.def_id;
+                    let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post);
+                    if check_must_not_suspend_def(
+                        fcx.tcx,
+                        def_id,
+                        hir_id,
+                        SuspendCheckData { descr_post, ..data },
+                    ) {
+                        has_emitted = true;
+                        break;
+                    }
+                }
+            }
+            has_emitted
+        }
+        ty::Tuple(ref tys) => {
+            let mut has_emitted = false;
+            let spans = if let Some(hir::ExprKind::Tup(comps)) = data.expr.map(|e| &e.kind) {
+                debug_assert_eq!(comps.len(), tys.len());
+                comps.iter().map(|e| e.span).collect()
+            } else {
+                vec![]
+            };
+            for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
+                let descr_post = &format!(" in tuple element {}", i);
+                let span = *spans.get(i).unwrap_or(&data.source_span);
+                if check_must_not_suspend_ty(
+                    fcx,
+                    ty,
+                    hir_id,
+                    SuspendCheckData { descr_post, source_span: span, ..data },
+                ) {
+                    has_emitted = true;
+                }
+            }
+            has_emitted
+        }
+        ty::Array(ty, len) => {
+            let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
+            check_must_not_suspend_ty(
+                fcx,
+                ty,
+                hir_id,
+                SuspendCheckData {
+                    descr_pre,
+                    plural_len: len.try_eval_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize
+                        + 1,
+                    ..data
+                },
+            )
+        }
+        _ => false,
+    }
+}
+
+fn check_must_not_suspend_def(
+    tcx: TyCtxt<'_>,
+    def_id: DefId,
+    hir_id: HirId,
+    data: SuspendCheckData<'_, '_>,
+) -> bool {
+    for attr in tcx.get_attrs(def_id).iter() {
+        if attr.has_name(sym::must_not_suspend) {
+            tcx.struct_span_lint_hir(
+                rustc_session::lint::builtin::MUST_NOT_SUSPEND,
+                hir_id,
+                data.source_span,
+                |lint| {
+                    let msg = format!(
+                        "{}`{}`{} held across a suspend point, but should not be",
+                        data.descr_pre,
+                        tcx.def_path_str(def_id),
+                        data.descr_post,
+                    );
+                    let mut err = lint.build(&msg);
+
+                    // add span pointing to the offending yield/await
+                    err.span_label(data.yield_span, "the value is held across this suspend point");
+
+                    // Add optional reason note
+                    if let Some(note) = attr.value_str() {
+                        // FIXME(guswynn): consider formatting this better
+                        err.span_note(data.source_span, &note.as_str());
+                    }
+
+                    // Add some quick suggestions on what to do
+                    // FIXME: can `drop` work as a suggestion here as well?
+                    err.span_help(
+                        data.source_span,
+                        "consider using a block (`{ ... }`) \
+                        to shrink the value's scope, ending before the suspend point",
+                    );
+
+                    err.emit();
+                },
+            );
+
+            return true;
+        }
+    }
+    false
+}
index 6006c8f7513d70d91eb3cd77187685c578273146..f7552c1f4eb0cae7e6281e52d553f3cae5a09ec6 100644 (file)
@@ -1,6 +1,7 @@
 use super::callee::DeferredCallResolution;
 use super::MaybeInProgressTables;
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefIdMap, LocalDefId};
 use rustc_hir::HirIdMap;
@@ -56,6 +57,11 @@ pub struct Inherited<'a, 'tcx> {
     pub(super) constness: hir::Constness,
 
     pub(super) body_id: Option<hir::BodyId>,
+
+    /// Whenever we introduce an adjustment from `!` into a type variable,
+    /// we record that type variable here. This is later used to inform
+    /// fallback. See the `fallback` module for details.
+    pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
 }
 
 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
@@ -121,6 +127,7 @@ pub(super) fn with_constness(
             deferred_call_resolutions: RefCell::new(Default::default()),
             deferred_cast_checks: RefCell::new(Vec::new()),
             deferred_generator_interiors: RefCell::new(Vec::new()),
+            diverging_type_vars: RefCell::new(Default::default()),
             constness,
             body_id,
         }
index 8e09aa97dcf345ea396f06fbbd7002576455d9a8..113d495f0ce93c499238702926154ab5afb2d1bc 100644 (file)
@@ -21,7 +21,7 @@
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable, WithConstness};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits;
@@ -331,7 +331,7 @@ pub fn lookup_method_in_trait(
         let trait_ref = ty::TraitRef::new(trait_def_id, substs);
 
         // Construct an obligation
-        let poly_trait_ref = trait_ref.to_poly_trait_ref();
+        let poly_trait_ref = ty::Binder::dummy(trait_ref);
         let obligation = traits::Obligation::misc(
             span,
             self.body_id,
@@ -413,7 +413,7 @@ pub fn lookup_method_in_trait(
         obligations.push(traits::Obligation::new(
             cause,
             self.param_env,
-            ty::PredicateKind::WellFormed(method_ty.into()).to_predicate(tcx),
+            ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx),
         ));
 
         let callee = MethodCallee { def_id, substs: trait_ref.substs, sig: fn_sig };
index cbfdce96bc57bdd0b1554f8b4e32ec1e8343faf6..5aa579f33a9d2148448ff80a0cd4c64b1d664be0 100644 (file)
@@ -21,9 +21,7 @@
 use rustc_middle::middle::stability;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
-use rustc_middle::ty::{
-    self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
-};
+use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::lev_distance::{find_best_match_for_name, lev_distance};
@@ -967,7 +965,7 @@ fn assemble_extension_candidates_for_trait(
 
         if self.tcx.is_trait_alias(trait_def_id) {
             // For trait aliases, assume all super-traits are relevant.
-            let bounds = iter::once(trait_ref.to_poly_trait_ref());
+            let bounds = iter::once(ty::Binder::dummy(trait_ref));
             self.elaborate_bounds(bounds, |this, new_trait_ref, item| {
                 let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
 
@@ -1372,7 +1370,7 @@ fn select_trait_candidate(
         trait_ref: ty::TraitRef<'tcx>,
     ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
         let cause = traits::ObligationCause::misc(self.span, self.body_id);
-        let predicate = trait_ref.to_poly_trait_ref().to_poly_trait_predicate();
+        let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate();
         let obligation = traits::Obligation::new(cause, self.param_env, predicate);
         traits::SelectionContext::new(self).select(&obligation)
     }
@@ -1470,7 +1468,8 @@ fn consider_probe(
                             }
                         }
                     }
-                    let predicate = trait_ref.without_const().to_predicate(self.tcx);
+                    let predicate =
+                        ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
                     let obligation = traits::Obligation::new(cause, self.param_env, predicate);
                     if !self.predicate_may_hold(&obligation) {
                         result = ProbeResult::NoMatch;
index 9744f4f6483c75f8fcaf72f9db79c36cbf204219..91a164ce063ea6cae022e8254e572e8149338bb9 100644 (file)
@@ -12,9 +12,7 @@
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::ty::fast_reject::simplify_type;
 use rustc_middle::ty::print::with_crate_prefix;
-use rustc_middle::ty::{
-    self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
-};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_span::lev_distance;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{source_map, FileName, Span};
@@ -53,7 +51,7 @@ fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
                                 .into()],
                         );
                         let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
-                        let poly_trait_ref = trait_ref.to_poly_trait_ref();
+                        let poly_trait_ref = ty::Binder::dummy(trait_ref);
                         let obligation = Obligation::misc(
                             span,
                             self.body_id,
index 53b99a14f379d2450c5656eaf87f8ed99e58fa5a..917bf4ecd8c4a9117a5e80a6421beadb7836d0e4 100644 (file)
@@ -602,7 +602,78 @@ fn compute_min_captures(
             }
         }
 
-        debug!("For closure={:?}, min_captures={:#?}", closure_def_id, root_var_min_capture_list);
+        debug!(
+            "For closure={:?}, min_captures before sorting={:?}",
+            closure_def_id, root_var_min_capture_list
+        );
+
+        // Now that we have the minimized list of captures, sort the captures by field id.
+        // This causes the closure to capture the upvars in the same order as the fields are
+        // declared which is also the drop order. Thus, in situations where we capture all the
+        // fields of some type, the obserable drop order will remain the same as it previously
+        // was even though we're dropping each capture individually.
+        // See https://github.com/rust-lang/project-rfc-2229/issues/42 and
+        // `src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs`.
+        for (_, captures) in &mut root_var_min_capture_list {
+            captures.sort_by(|capture1, capture2| {
+                for (p1, p2) in capture1.place.projections.iter().zip(&capture2.place.projections) {
+                    // We do not need to look at the `Projection.ty` fields here because at each
+                    // step of the iteration, the projections will either be the same and therefore
+                    // the types must be as well or the current projection will be different and
+                    // we will return the result of comparing the field indexes.
+                    match (p1.kind, p2.kind) {
+                        // Paths are the same, continue to next loop.
+                        (ProjectionKind::Deref, ProjectionKind::Deref) => {}
+                        (ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _))
+                            if i1 == i2 => {}
+
+                        // Fields are different, compare them.
+                        (ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _)) => {
+                            return i1.cmp(&i2);
+                        }
+
+                        // We should have either a pair of `Deref`s or a pair of `Field`s.
+                        // Anything else is a bug.
+                        (
+                            l @ (ProjectionKind::Deref | ProjectionKind::Field(..)),
+                            r @ (ProjectionKind::Deref | ProjectionKind::Field(..)),
+                        ) => bug!(
+                            "ProjectionKinds Deref and Field were mismatched: ({:?}, {:?})",
+                            l,
+                            r
+                        ),
+                        (
+                            l
+                            @
+                            (ProjectionKind::Index
+                            | ProjectionKind::Subslice
+                            | ProjectionKind::Deref
+                            | ProjectionKind::Field(..)),
+                            r
+                            @
+                            (ProjectionKind::Index
+                            | ProjectionKind::Subslice
+                            | ProjectionKind::Deref
+                            | ProjectionKind::Field(..)),
+                        ) => bug!(
+                            "ProjectionKinds Index or Subslice were unexpected: ({:?}, {:?})",
+                            l,
+                            r
+                        ),
+                    }
+                }
+
+                unreachable!(
+                    "we captured two identical projections: capture1 = {:?}, capture2 = {:?}",
+                    capture1, capture2
+                );
+            });
+        }
+
+        debug!(
+            "For closure={:?}, min_captures after sorting={:#?}",
+            closure_def_id, root_var_min_capture_list
+        );
         typeck_results.closure_min_captures.insert(closure_def_id, root_var_min_capture_list);
     }
 
index cb07fcf5fef5813fba8341be925567b9d55df4cc..48204590468a0af0e8faa945446daf3b5390164e 100644 (file)
@@ -2,7 +2,7 @@
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -12,7 +12,7 @@
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
 use rustc_middle::hir::map as hir_map;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
     self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@@ -20,7 +20,6 @@
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
-use rustc_trait_selection::opaque_types::may_define_opaque_type;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
 
@@ -77,14 +76,14 @@ fn with_fcx<F>(&mut self, f: F)
 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
 /// the types first.
+#[instrument(skip(tcx), level = "debug")]
 pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
     let item = tcx.hir().expect_item(hir_id);
 
     debug!(
-        "check_item_well_formed(it.def_id={:?}, it.name={})",
-        item.def_id,
-        tcx.def_path_str(def_id.to_def_id())
+        ?item.def_id,
+        item.name = ? tcx.def_path_str(def_id.to_def_id())
     );
 
     match item.kind {
@@ -201,6 +200,59 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     };
     check_object_unsafe_self_trait_by_name(tcx, &trait_item);
     check_associated_item(tcx, trait_item.hir_id(), span, method_sig);
+
+    let encl_trait_hir_id = tcx.hir().get_parent_item(hir_id);
+    let encl_trait = tcx.hir().expect_item(encl_trait_hir_id);
+    let encl_trait_def_id = encl_trait.def_id.to_def_id();
+    let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
+        Some("fn")
+    } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
+        Some("fn_mut")
+    } else {
+        None
+    };
+
+    if let (Some(fn_lang_item_name), "call") =
+        (fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str())
+    {
+        // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
+        // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
+        if let Some(hir::FnSig { decl, span, .. }) = method_sig {
+            if let &[self_ty, _] = &decl.inputs {
+                if !matches!(self_ty.kind, hir::TyKind::Rptr(_, _)) {
+                    tcx.sess
+                        .struct_span_err(
+                            self_ty.span,
+                            &format!(
+                                "first argument of `call` in `{}` lang item must be a reference",
+                                fn_lang_item_name
+                            ),
+                        )
+                        .emit();
+                }
+            } else {
+                tcx.sess
+                    .struct_span_err(
+                        *span,
+                        &format!(
+                            "`call` function in `{}` lang item takes exactly two arguments",
+                            fn_lang_item_name
+                        ),
+                    )
+                    .emit();
+            }
+        } else {
+            tcx.sess
+                .struct_span_err(
+                    trait_item.span,
+                    &format!(
+                        "`call` trait item in `{}` lang item must be a function",
+                        fn_lang_item_name
+                    ),
+                )
+                .emit();
+        }
+    }
 }
 
 fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
@@ -541,10 +593,10 @@ fn check_type_defn<'tcx, F>(
                 fcx.register_predicate(traits::Obligation::new(
                     cause,
                     fcx.param_env,
-                    ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
+                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
                         ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
                         discr_substs,
-                    ))
+                    )))
                     .to_predicate(tcx),
                 ));
             }
@@ -557,8 +609,9 @@ fn check_type_defn<'tcx, F>(
     });
 }
 
+#[instrument(skip(tcx, item))]
 fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
-    debug!("check_trait: {:?}", item.def_id);
+    debug!(?item.def_id);
 
     let trait_def = tcx.trait_def(item.def_id);
     if trait_def.is_marker
@@ -712,13 +765,13 @@ fn check_impl<'tcx>(
 }
 
 /// Checks where-clauses and inline bounds that are declared on `def_id`.
+#[instrument(skip(fcx), level = "debug")]
 fn check_where_clauses<'tcx, 'fcx>(
     fcx: &FnCtxt<'fcx, 'tcx>,
     span: Span,
     def_id: DefId,
     return_ty: Option<(Ty<'tcx>, Span)>,
 ) {
-    debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty);
     let tcx = fcx.tcx;
 
     let predicates = tcx.predicates_of(def_id);
@@ -888,17 +941,15 @@ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy
 
     let predicates = predicates.instantiate_identity(tcx);
 
-    if let Some((mut return_ty, span)) = return_ty {
+    if let Some((return_ty, _)) = return_ty {
         if return_ty.has_infer_types_or_consts() {
             fcx.select_obligations_where_possible(false, |_| {});
-            return_ty = fcx.resolve_vars_if_possible(return_ty);
         }
-        check_opaque_types(fcx, def_id.expect_local(), span, return_ty);
     }
 
     let predicates = fcx.normalize_associated_types_in(span, predicates);
 
-    debug!("check_where_clauses: predicates={:?}", predicates.predicates);
+    debug!(?predicates.predicates);
     assert_eq!(predicates.predicates.len(), predicates.spans.len());
     let wf_obligations =
         iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| {
@@ -984,143 +1035,6 @@ fn check_fn_or_method<'fcx, 'tcx>(
     check_where_clauses(fcx, span, def_id, Some((sig.output(), hir_decl.output.span())));
 }
 
-/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
-/// laid for "higher-order pattern unification".
-/// This ensures that inference is tractable.
-/// In particular, definitions of opaque types can only use other generics as arguments,
-/// and they cannot repeat an argument. Example:
-///
-/// ```rust
-/// type Foo<A, B> = impl Bar<A, B>;
-///
-/// // Okay -- `Foo` is applied to two distinct, generic types.
-/// fn a<T, U>() -> Foo<T, U> { .. }
-///
-/// // Not okay -- `Foo` is applied to `T` twice.
-/// fn b<T>() -> Foo<T, T> { .. }
-///
-/// // Not okay -- `Foo` is applied to a non-generic type.
-/// fn b<T>() -> Foo<T, u32> { .. }
-/// ```
-///
-fn check_opaque_types<'fcx, 'tcx>(
-    fcx: &FnCtxt<'fcx, 'tcx>,
-    fn_def_id: LocalDefId,
-    span: Span,
-    ty: Ty<'tcx>,
-) {
-    trace!("check_opaque_types(fn_def_id={:?}, ty={:?})", fn_def_id, ty);
-    let tcx = fcx.tcx;
-
-    ty.fold_with(&mut ty::fold::BottomUpFolder {
-        tcx,
-        ty_op: |ty| {
-            if let ty::Opaque(def_id, substs) = *ty.kind() {
-                trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
-                let generics = tcx.generics_of(def_id);
-
-                let opaque_hir_id = if let Some(local_id) = def_id.as_local() {
-                    tcx.hir().local_def_id_to_hir_id(local_id)
-                } else {
-                    // Opaque types from other crates won't have defining uses in this crate.
-                    return ty;
-                };
-                if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) =
-                    tcx.hir().expect_item(opaque_hir_id).kind
-                {
-                    // No need to check return position impl trait (RPIT)
-                    // because for type and const parameters they are correct
-                    // by construction: we convert
-                    //
-                    // fn foo<P0..Pn>() -> impl Trait
-                    //
-                    // into
-                    //
-                    // type Foo<P0...Pn>
-                    // fn foo<P0..Pn>() -> Foo<P0...Pn>.
-                    //
-                    // For lifetime parameters we convert
-                    //
-                    // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
-                    //
-                    // into
-                    //
-                    // type foo::<'p0..'pn>::Foo<'q0..'qm>
-                    // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
-                    //
-                    // which would error here on all of the `'static` args.
-                    return ty;
-                }
-                if !may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
-                    return ty;
-                }
-                trace!("check_opaque_types: may define, generics={:#?}", generics);
-                let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
-                for (i, arg) in substs.iter().enumerate() {
-                    let arg_is_param = match arg.unpack() {
-                        GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
-
-                        GenericArgKind::Lifetime(region) if let ty::ReStatic = region => {
-                            tcx.sess
-                                .struct_span_err(
-                                    span,
-                                    "non-defining opaque type use in defining scope",
-                                )
-                                .span_label(
-                                    tcx.def_span(generics.param_at(i, tcx).def_id),
-                                    "cannot use static lifetime; use a bound lifetime \
-                                                instead or remove the lifetime parameter from the \
-                                                opaque type",
-                                )
-                                .emit();
-                            continue;
-                        }
-
-                        GenericArgKind::Lifetime(_) => true,
-
-                        GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
-                    };
-
-                    if arg_is_param {
-                        seen_params.entry(arg).or_default().push(i);
-                    } else {
-                        // Prevent `fn foo() -> Foo<u32>` from being defining.
-                        let opaque_param = generics.param_at(i, tcx);
-                        tcx.sess
-                            .struct_span_err(span, "non-defining opaque type use in defining scope")
-                            .span_note(
-                                tcx.def_span(opaque_param.def_id),
-                                &format!(
-                                    "used non-generic {} `{}` for generic parameter",
-                                    opaque_param.kind.descr(),
-                                    arg,
-                                ),
-                            )
-                            .emit();
-                    }
-                } // for (arg, param)
-
-                for (_, indices) in seen_params {
-                    if indices.len() > 1 {
-                        let descr = generics.param_at(indices[0], tcx).kind.descr();
-                        let spans: Vec<_> = indices
-                            .into_iter()
-                            .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
-                            .collect();
-                        tcx.sess
-                            .struct_span_err(span, "non-defining opaque type use in defining scope")
-                            .span_note(spans, &format!("{} used multiple times", descr))
-                            .emit();
-                    }
-                }
-            } // if let Opaque
-            ty
-        },
-        lt_op: |lt| lt,
-        ct_op: |ct| ct,
-    });
-}
-
 const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
      `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
      of the previous types except `Self`)";
@@ -1290,10 +1204,10 @@ fn receiver_is_implemented(
     cause: ObligationCause<'tcx>,
     receiver_ty: Ty<'tcx>,
 ) -> bool {
-    let trait_ref = ty::TraitRef {
+    let trait_ref = ty::Binder::dummy(ty::TraitRef {
         def_id: receiver_trait_def_id,
         substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
-    };
+    });
 
     let obligation = traits::Obligation::new(
         cause,
@@ -1439,20 +1353,23 @@ fn nested_visit_map(&mut self) -> hir_visit::NestedVisitorMap<Self::Map> {
         hir_visit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
     }
 
+    #[instrument(skip(self, i), level = "debug")]
     fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
-        debug!("visit_item: {:?}", i);
+        trace!(?i);
         self.tcx.ensure().check_item_well_formed(i.def_id);
         hir_visit::walk_item(self, i);
     }
 
+    #[instrument(skip(self, trait_item), level = "debug")]
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        debug!("visit_trait_item: {:?}", trait_item);
+        trace!(?trait_item);
         self.tcx.ensure().check_trait_item_well_formed(trait_item.def_id);
         hir_visit::walk_trait_item(self, trait_item);
     }
 
+    #[instrument(skip(self, impl_item), level = "debug")]
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        debug!("visit_impl_item: {:?}", impl_item);
+        trace!(?impl_item);
         self.tcx.ensure().check_impl_item_well_formed(impl_item.def_id);
         hir_visit::walk_impl_item(self, impl_item);
     }
index c7be9e2123512cae236c673adf01cec411436b32..f3fe09ac0033d4802b8d1797d40fb91c57b343b2 100644 (file)
@@ -401,7 +401,7 @@ fn check_primitive_impl(
         lang: &str,
         ty: &str,
         span: Span,
-        assoc_items: &[hir::ImplItemRef<'_>],
+        assoc_items: &[hir::ImplItemRef],
     ) {
         match (lang_def_id, lang_def_id2) {
             (Some(lang_def_id), _) if lang_def_id == impl_def_id.to_def_id() => {
index 1bc7bc3e063d4be1c14c299c0355cc2182feb201..51f9f459af1c56390e1e37ffe92633f55eccc64b 100644 (file)
@@ -40,7 +40,7 @@
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::util::Discr;
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, Ty, TyCtxt};
 use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
@@ -2042,7 +2042,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
             match item.kind {
                 ItemKind::Impl(ref impl_) => {
                     if impl_.defaultness.is_default() {
-                        is_default_impl_trait = tcx.impl_trait_ref(def_id);
+                        is_default_impl_trait = tcx
+                            .impl_trait_ref(def_id)
+                            .map(|trait_ref| ty::Binder::dummy(trait_ref));
                     }
                     &impl_.generics
                 }
@@ -2122,10 +2124,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
     // (see below). Recall that a default impl is not itself an impl, but rather a
     // set of defaults that can be incorporated into another impl.
     if let Some(trait_ref) = is_default_impl_trait {
-        predicates.insert((
-            trait_ref.to_poly_trait_ref().without_const().to_predicate(tcx),
-            tcx.def_span(def_id),
-        ));
+        predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
     }
 
     // Collect the region predicates that were declared inline as
@@ -2238,8 +2237,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                         }
                         _ => bug!(),
                     };
-                    let pred = ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
-                        .to_predicate(icx.tcx);
+                    let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
+                        ty::OutlivesPredicate(r1, r2),
+                    ))
+                    .to_predicate(icx.tcx);
 
                     (pred, span)
                 }))
@@ -2304,7 +2305,8 @@ fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
                 assert_eq!(uv.promoted, None);
                 let span = self.tcx.hir().span(c.hir_id);
                 self.preds.insert((
-                    ty::PredicateKind::ConstEvaluatable(uv.shrink()).to_predicate(self.tcx),
+                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
+                        .to_predicate(self.tcx),
                     span,
                 ));
             }
@@ -2778,10 +2780,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
         } else if attr.has_name(sym::thread_local) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
         } else if attr.has_name(sym::track_caller) {
-            if tcx.is_closure(id) || tcx.fn_sig(id).abi() != abi::Abi::Rust {
+            if !tcx.is_closure(id) && tcx.fn_sig(id).abi() != abi::Abi::Rust {
                 struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
                     .emit();
             }
+            if tcx.is_closure(id) && !tcx.features().closure_track_caller {
+                feature_err(
+                    &tcx.sess.parse_sess,
+                    sym::closure_track_caller,
+                    attr.span,
+                    "`#[track_caller]` on closures is currently unstable",
+                )
+                .emit();
+            }
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
         } else if attr.has_name(sym::export_name) {
             if let Some(s) = attr.value_str() {
index 7f9afaae0eaa2675f8273aaf32af2ee7e9c5a53b..7a14d7f3d283d0afe0a412a4c49cd2bd447dfd8c 100644 (file)
@@ -1,4 +1,3 @@
-use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, ErrorReported, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -7,7 +6,7 @@
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{HirId, Node};
 use rustc_middle::hir::map::Map;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, SubstsRef};
+use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_span::symbol::Ident;
@@ -539,6 +538,25 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 }
 
 #[instrument(skip(tcx), level = "debug")]
+/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
+/// laid for "higher-order pattern unification".
+/// This ensures that inference is tractable.
+/// In particular, definitions of opaque types can only use other generics as arguments,
+/// and they cannot repeat an argument. Example:
+///
+/// ```rust
+/// type Foo<A, B> = impl Bar<A, B>;
+///
+/// // Okay -- `Foo` is applied to two distinct, generic types.
+/// fn a<T, U>() -> Foo<T, U> { .. }
+///
+/// // Not okay -- `Foo` is applied to `T` twice.
+/// fn b<T>() -> Foo<T, T> { .. }
+///
+/// // Not okay -- `Foo` is applied to a non-generic type.
+/// fn b<T>() -> Foo<T, u32> { .. }
+/// ```
+///
 fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
     use rustc_hir::{Expr, ImplItem, Item, TraitItem};
 
@@ -584,50 +602,8 @@ fn check(&mut self, def_id: LocalDefId) {
                 // FIXME(oli-obk): trace the actual span from inference to improve errors.
                 let span = self.tcx.def_span(def_id);
 
-                // HACK(eddyb) this check shouldn't be needed, as `wfcheck`
-                // performs the same checks, in theory, but I've kept it here
-                // using `delay_span_bug`, just in case `wfcheck` slips up.
-                let opaque_generics = self.tcx.generics_of(self.def_id);
-                let mut used_params: FxHashSet<_> = FxHashSet::default();
-                for (i, arg) in opaque_type_key.substs.iter().enumerate() {
-                    let arg_is_param = match arg.unpack() {
-                        GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
-                        GenericArgKind::Lifetime(lt) => {
-                            matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
-                        }
-                        GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
-                    };
-
-                    if arg_is_param {
-                        if !used_params.insert(arg) {
-                            // There was already an entry for `arg`, meaning a generic parameter
-                            // was used twice.
-                            self.tcx.sess.delay_span_bug(
-                                span,
-                                &format!(
-                                    "defining opaque type use restricts opaque \
-                                     type by using the generic parameter `{}` twice",
-                                    arg,
-                                ),
-                            );
-                        }
-                    } else {
-                        let param = opaque_generics.param_at(i, self.tcx);
-                        self.tcx.sess.delay_span_bug(
-                            span,
-                            &format!(
-                                "defining opaque type use does not fully define opaque type: \
-                                 generic parameter `{}` is specified as concrete {} `{}`",
-                                param.name,
-                                param.kind.descr(),
-                                arg,
-                            ),
-                        );
-                    }
-                }
-
                 if let Some((prev_span, prev_ty)) = self.found {
-                    if *concrete_type != prev_ty {
+                    if *concrete_type != prev_ty && !(*concrete_type, prev_ty).references_error() {
                         debug!(?span);
                         // Found different concrete types for the opaque type.
                         let mut err = self.tcx.sess.struct_span_err(
index b7ede0e4bf25175ea966b2816a29da71401bd5b8..39bcf8999323d7fb7a9a877cda60ee0d4b355bdb 100644 (file)
@@ -83,7 +83,8 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
                     traits::Obligation::new(
                         cause,
                         self.param_env,
-                        ty::PredicateKind::WellFormed(tcx_ty.into()).to_predicate(self.tcx),
+                        ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into()))
+                            .to_predicate(self.tcx),
                     ),
                 );
 
index 9b23bf241cc6fa5ec87fa0a274e623da78916a6a..5d2f8fc4242756b798c1c9485cf999603f78fce3 100644 (file)
@@ -97,7 +97,7 @@ fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {}
 fn enforce_impl_params_are_constrained(
     tcx: TyCtxt<'_>,
     impl_def_id: LocalDefId,
-    impl_item_refs: &[hir::ImplItemRef<'_>],
+    impl_item_refs: &[hir::ImplItemRef],
 ) {
     // Every lifetime used in an associated type must be constrained.
     let impl_self_ty = tcx.type_of(impl_def_id);
@@ -228,7 +228,7 @@ impl trait, self type, or predicates",
 }
 
 /// Enforce that we do not have two items in an impl with the same name.
-fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef<'_>]) {
+fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) {
     let mut seen_type_items = FxHashMap::default();
     let mut seen_value_items = FxHashMap::default();
     for impl_item_ref in impl_item_refs {
index 70a2ba7fcd9d9cc5e2c54238246e21b2d2ec86f0..9c6efffdaf0fe3d1d043d784c58143ac4281f2aa 100644 (file)
@@ -104,13 +104,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
                 |(ty::OutlivesPredicate(kind1, region2), &span)| {
                     match kind1.unpack() {
                         GenericArgKind::Type(ty1) => Some((
-                            ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty1, region2))
-                                .to_predicate(tcx),
+                            ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
+                                ty::OutlivesPredicate(ty1, region2),
+                            ))
+                            .to_predicate(tcx),
                             span,
                         )),
                         GenericArgKind::Lifetime(region1) => Some((
-                            ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
-                                region1, region2,
+                            ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
+                                ty::OutlivesPredicate(region1, region2),
                             ))
                             .to_predicate(tcx),
                             span,
index 7e69ad21d034326a9c1fac72b80946e96a0c6fe8..2e3db4d6d655f53447438c62ec0c76ad90b7a397 100644 (file)
@@ -1,6 +1,7 @@
 use crate::structured_errors::StructuredDiagnostic;
 use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
+use rustc_middle::hir::map::fn_sig;
 use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
 use rustc_middle::ty::{self as ty, TyCtxt};
 use rustc_session::Session;
@@ -292,12 +293,30 @@ fn get_type_or_const_args_suggestions_from_param_names(
         &self,
         num_params_to_take: usize,
     ) -> String {
+        let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(|node| fn_sig(node));
+        let is_used_in_input = |def_id| {
+            fn_sig.map_or(false, |fn_sig| {
+                fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
+                    hir::TyKind::Path(hir::QPath::Resolved(
+                        None,
+                        hir::Path { res: hir::def::Res::Def(_, id), .. },
+                    )) if *id == def_id => true,
+                    _ => false,
+                })
+            })
+        };
         self.gen_params
             .params
             .iter()
             .skip(self.params_offset + self.num_provided_type_or_const_args())
             .take(num_params_to_take)
-            .map(|param| param.name.to_string())
+            .map(|param| match param.kind {
+                // This is being infered from the item's inputs, no need to set it.
+                ty::GenericParamDefKind::Type { .. } if is_used_in_input(param.def_id) => {
+                    "_".to_string()
+                }
+                _ => param.name.to_string(),
+            })
             .collect::<Vec<_>>()
             .join(", ")
     }
index 3ed3c2382cac69193a07129fa91d9b6e2a9981f3..4a5b0fcf03709ff944fe4e612327bbeaee3cb70e 100644 (file)
@@ -307,7 +307,6 @@ unsafe fn shrink(
 }
 
 /// The allocator for unique pointers.
-// This function must not unwind. If it does, MIR codegen will fail.
 #[cfg(all(not(no_global_oom_handling), not(test)))]
 #[lang = "exchange_malloc"]
 #[inline]
index 722168523763a7bc7b0999aef90934ecf104ebc6..2b3a18a439fc92c56d2b6f530c73e85ce03db3c9 100644 (file)
@@ -1086,6 +1086,7 @@ fn drop(&mut self) {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Box<T> {
     /// Creates a `Box<T>`, with the `Default` value for T.
@@ -1394,6 +1395,7 @@ fn from(s: Box<str, A>) -> Self {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_array", since = "1.45.0")]
 impl<T, const N: usize> From<[T; N]> for Box<[T]> {
     /// Converts a `[T; N]` into a `Box<[T]>`
index 28e4f8bba05c8d5272e477f98ad4a00e57f5d3fd..4ed3702f7d22479d8ab1e77be4c49dc139f5b1ec 100644 (file)
@@ -3,7 +3,7 @@
 //! Insertion and popping the largest element have *O*(log(*n*)) time complexity.
 //! Checking the largest element is *O*(1). Converting a vector to a binary heap
 //! can be done in-place, and has *O*(*n*) complexity. A binary heap can also be
-//! converted to a sorted vector in-place, allowing it to be used for an *O*(*n* \* log(*n*))
+//! converted to a sorted vector in-place, allowing it to be used for an *O*(*n* * log(*n*))
 //! in-place heapsort.
 //!
 //! # Examples
 /// This will be a max-heap.
 ///
 /// It is a logic error for an item to be modified in such a way that the
-/// item's ordering relative to any other item, as determined by the `Ord`
+/// item's ordering relative to any other item, as determined by the [`Ord`]
 /// trait, changes while it is in the heap. This is normally only possible
-/// through `Cell`, `RefCell`, global state, I/O, or unsafe code. The
+/// through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. The
 /// behavior resulting from such a logic error is not specified, but will
 /// not result in undefined behavior. This could include panics, incorrect
 /// results, aborts, memory leaks, and non-termination.
 ///
 /// ## Min-heap
 ///
-/// Either `std::cmp::Reverse` or a custom `Ord` implementation can be used to
+/// Either [`core::cmp::Reverse`] or a custom [`Ord`] implementation can be used to
 /// make `BinaryHeap` a min-heap. This makes `heap.pop()` return the smallest
 /// value instead of the greatest one.
 ///
 ///
 /// # Time complexity
 ///
-/// | [push] | [pop]     | [peek]/[peek\_mut] |
-/// |--------|-----------|--------------------|
-/// | O(1)~  | *O*(log(*n*)) | *O*(1)               |
+/// | [push]  | [pop]         | [peek]/[peek\_mut] |
+/// |---------|---------------|--------------------|
+/// | *O*(1)~ | *O*(log(*n*)) | *O*(1)             |
 ///
 /// The value for `push` is an expected cost; the method documentation gives a
 /// more detailed analysis.
 ///
+/// [`core::cmp::Reverse`]: core::cmp::Reverse
+/// [`Ord`]: core::cmp::Ord
+/// [`Cell`]: core::cell::Cell
+/// [`RefCell`]: core::cell::RefCell
 /// [push]: BinaryHeap::push
 /// [pop]: BinaryHeap::pop
 /// [peek]: BinaryHeap::peek
@@ -1255,9 +1259,10 @@ impl<T> FusedIterator for Iter<'_, T> {}
 /// An owning iterator over the elements of a `BinaryHeap`.
 ///
 /// This `struct` is created by [`BinaryHeap::into_iter()`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: BinaryHeap::into_iter
+/// [`IntoIterator`]: core::iter::IntoIterator
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct IntoIter<T> {
index 10298e117f5b42c7502dd229180c8bfb7c381f1d..3b7c92818f698facd8ae4aea9d7a12f182f80b6e 100644 (file)
@@ -327,9 +327,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// An owning iterator over the entries of a `BTreeMap`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`BTreeMap`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: IntoIterator::into_iter
+/// [`IntoIterator`]: core::iter::IntoIterator
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_insignificant_dtor]
 pub struct IntoIter<K, V> {
index c664e201aec544067d825faf5633b9c90a253020..16150ceeb62c116a3a6e701ef74f0338785fe259 100644 (file)
@@ -107,9 +107,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// An owning iterator over the items of a `BTreeSet`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`BTreeSet`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: BTreeSet#method.into_iter
+/// [`IntoIterator`]: core::iter::IntoIterator
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct IntoIter<T> {
index cef9bb60b885e1153096a61ab475ba0b588b97d8..a769c558b4fa90f39e7e8ed344c677ae718edc6b 100644 (file)
 /// let list = LinkedList::from([1, 2, 3]);
 /// ```
 ///
-/// NOTE: It is almost always better to use `Vec` or `VecDeque` because
+/// NOTE: It is almost always better to use [`Vec`] or [`VecDeque`] because
 /// array-based containers are generally faster,
 /// more memory efficient, and make better use of CPU cache.
+///
+/// [`Vec`]: crate::vec::Vec
+/// [`VecDeque`]: super::vec_deque::VecDeque
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")]
 #[rustc_insignificant_dtor]
@@ -122,9 +125,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// An owning iterator over the elements of a `LinkedList`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`LinkedList`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: LinkedList::into_iter
+/// [`IntoIterator`]: core::iter::IntoIterator
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
@@ -632,6 +636,8 @@ pub fn clear(&mut self) {
     /// Returns `true` if the `LinkedList` contains an element equal to the
     /// given value.
     ///
+    /// This operation should compute in *O*(*n*) time.
+    ///
     /// # Examples
     ///
     /// ```
@@ -657,6 +663,8 @@ pub fn contains(&self, x: &T) -> bool
     /// Provides a reference to the front element, or `None` if the list is
     /// empty.
     ///
+    /// This operation should compute in *O*(1) time.
+    ///
     /// # Examples
     ///
     /// ```
@@ -677,6 +685,8 @@ pub fn front(&self) -> Option<&T> {
     /// Provides a mutable reference to the front element, or `None` if the list
     /// is empty.
     ///
+    /// This operation should compute in *O*(1) time.
+    ///
     /// # Examples
     ///
     /// ```
@@ -703,6 +713,8 @@ pub fn front_mut(&mut self) -> Option<&mut T> {
     /// Provides a reference to the back element, or `None` if the list is
     /// empty.
     ///
+    /// This operation should compute in *O*(1) time.
+    ///
     /// # Examples
     ///
     /// ```
@@ -723,6 +735,8 @@ pub fn back(&self) -> Option<&T> {
     /// Provides a mutable reference to the back element, or `None` if the list
     /// is empty.
     ///
+    /// This operation should compute in *O*(1) time.
+    ///
     /// # Examples
     ///
     /// ```
index 54a157be0b96acdfecab5838f1385f0c1b939db1..55f6138cd0f31407217fd4ef17fb391a5f55c80d 100644 (file)
@@ -8,9 +8,10 @@
 /// An owning iterator over the elements of a `VecDeque`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: VecDeque::into_iter
+/// [`IntoIterator`]: core::iter::IntoIterator
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<
index 8c5125d208263ae34003c1284e7f82df66e39920..878d8dc5502df8d552dc4bed84165ad592876d33 100644 (file)
 //! provides some helper methods.
 //!
 //! Additionally, the return value of this function is [`fmt::Result`] which is a
-//! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
+//! type alias of <code>[Result]<(), [std::fmt::Error]></code>. Formatting implementations
 //! should ensure that they propagate errors from the [`Formatter`] (e.g., when
 //! calling [`write!`]). However, they should never return errors spuriously. That
 //! is, a formatting implementation must and may only return an error if the
 //! it would internally pass around this structure until it has been determined
 //! where output should go to.
 //!
-//! [`fmt::Result`]: Result
-//! [`Result`]: core::result::Result
-//! [`std::fmt::Error`]: Error
-//! [`write!`]: core::write
-//! [`write`]: core::write
-//! [`format!`]: crate::format
-//! [`to_string`]: crate::string::ToString
-//! [`writeln!`]: core::writeln
+//! [`fmt::Result`]: Result "fmt::Result"
+//! [Result]: core::result::Result "std::result::Result"
+//! [std::fmt::Error]: Error "fmt::Error"
+//! [`write`]: write() "fmt::write"
+//! [`to_string`]: crate::string::ToString::to_string "ToString::to_string"
 //! [`write_fmt`]: ../../std/io/trait.Write.html#method.write_fmt
 //! [`std::io::Write`]: ../../std/io/trait.Write.html
-//! [`print!`]: ../../std/macro.print.html
-//! [`println!`]: ../../std/macro.println.html
-//! [`eprint!`]: ../../std/macro.eprint.html
-//! [`eprintln!`]: ../../std/macro.eprintln.html
-//! [`format_args!`]: core::format_args
-//! [`fmt::Arguments`]: Arguments
-//! [`format`]: crate::format
+//! [`print!`]: ../../std/macro.print.html "print!"
+//! [`println!`]: ../../std/macro.println.html "println!"
+//! [`eprint!`]: ../../std/macro.eprint.html "eprint!"
+//! [`eprintln!`]: ../../std/macro.eprintln.html "eprintln!"
+//! [`fmt::Arguments`]: Arguments "fmt::Arguments"
+//! [`format`]: format() "fmt::format"
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 78356f7a48ac8c2e9ebc2c4ee7da1085df6486b7..81e97805a72142a65408b0ebba48e6ad3214bc75 100644 (file)
@@ -782,9 +782,7 @@ impl<T: ?Sized> Rc<T> {
     /// Consumes the `Rc`, returning the wrapped pointer.
     ///
     /// To avoid a memory leak the pointer must be converted back to an `Rc` using
-    /// [`Rc::from_raw`][from_raw].
-    ///
-    /// [from_raw]: Rc::from_raw
+    /// [`Rc::from_raw`].
     ///
     /// # Examples
     ///
@@ -835,7 +833,7 @@ pub fn as_ptr(this: &Self) -> *const T {
     /// and alignment as `T`. This is trivially true if `U` is `T`.
     /// Note that if `U` is not `T` but has the same size and alignment, this is
     /// basically like transmuting references of different types. See
-    /// [`mem::transmute`][transmute] for more information on what
+    /// [`mem::transmute`] for more information on what
     /// restrictions apply in this case.
     ///
     /// The user of `from_raw` has to make sure a specific value of `T` is only
@@ -845,7 +843,6 @@ pub fn as_ptr(this: &Self) -> *const T {
     /// even if the returned `Rc<T>` is never accessed.
     ///
     /// [into_raw]: Rc::into_raw
-    /// [transmute]: core::mem::transmute
     ///
     /// # Examples
     ///
@@ -1087,8 +1084,6 @@ pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
     /// assert!(Rc::ptr_eq(&five, &same_five));
     /// assert!(!Rc::ptr_eq(&five, &other_five));
     /// ```
-    ///
-    /// [`ptr::eq`]: core::ptr::eq
     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
         this.ptr.as_ptr() == other.ptr.as_ptr()
     }
@@ -1994,7 +1989,7 @@ fn to_rc_slice(self) -> Rc<[T]> {
 
 /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
 /// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
-/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
+/// pointer, which returns an <code>[Option]<[Rc]\<T>></code>.
 ///
 /// Since a `Weak` reference does not count towards ownership, it will not
 /// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no
@@ -2091,7 +2086,7 @@ impl<T: ?Sized> Weak<T> {
     /// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
     /// ```
     ///
-    /// [`null`]: core::ptr::null
+    /// [`null`]: ptr::null
     #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut RcBox<T> = NonNull::as_ptr(self.ptr);
@@ -2318,8 +2313,6 @@ fn inner(&self) -> Option<WeakInner<'_>> {
     /// let third = Rc::downgrade(&third_rc);
     /// assert!(!first.ptr_eq(&third));
     /// ```
-    ///
-    /// [`ptr::eq`]: core::ptr::eq
     #[inline]
     #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
@@ -2401,7 +2394,6 @@ impl<T> Default for Weak<T> {
     /// Constructs a new `Weak<T>`, without allocating any memory.
     /// Calling [`upgrade`] on the return value always gives [`None`].
     ///
-    /// [`None`]: Option
     /// [`upgrade`]: Weak::upgrade
     ///
     /// # Examples
index 6568d9f9907b998156293c7357b19f3eee447c87..57c38f2c0a9c5ef0eb153ce32b48ae94c67b95cb 100644 (file)
@@ -79,7 +79,7 @@
 ///
 /// # Examples
 ///
-/// You can create a `String` from [a literal string][`str`] with [`String::from`]:
+/// You can create a `String` from [a literal string][`&str`] with [`String::from`]:
 ///
 /// [`String::from`]: From::from
 ///
 /// println!("The first letter of s is {}", s[0]); // ERROR!!!
 /// ```
 ///
-/// [`OsString`]: ../../std/ffi/struct.OsString.html
+/// [`OsString`]: ../../std/ffi/struct.OsString.html "ffi::OsString"
 ///
 /// Indexing is intended to be a constant-time operation, but UTF-8 encoding
 /// does not allow us to do this. Furthermore, it's not clear what sort of
 ///
 /// # Deref
 ///
-/// `String`s implement [`Deref`]`<Target=str>`, and so inherit all of [`str`]'s
+/// `String` implements <code>[Deref]<Target = [str]></code>, and so inherits all of [`str`]'s
 /// methods. In addition, this means that you can pass a `String` to a
 /// function which takes a [`&str`] by using an ampersand (`&`):
 ///
 /// to explicitly extract the string slice containing the string. The second
 /// way changes `example_func(&example_string);` to
 /// `example_func(&*example_string);`. In this case we are dereferencing a
-/// `String` to a [`str`][`&str`], then referencing the [`str`][`&str`] back to
+/// `String` to a [`str`], then referencing the [`str`] back to
 /// [`&str`]. The second way is more idiomatic, however both work to do the
 /// conversion explicitly rather than relying on the implicit conversion.
 ///
 ///
 /// Here, there's no need to allocate more memory inside the loop.
 ///
-/// [`str`]: prim@str
-/// [`&str`]: prim@str
-/// [`Deref`]: core::ops::Deref
+/// [str]: prim@str "str"
+/// [`str`]: prim@str "str"
+/// [`&str`]: prim@str "&str"
+/// [Deref]: core::ops::Deref "ops::Deref"
+/// [`Deref`]: core::ops::Deref "ops::Deref"
 /// [`as_str()`]: String::as_str
 #[derive(PartialOrd, Eq, Ord)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "string_type")]
@@ -308,10 +310,10 @@ pub struct String {
 /// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
 /// through the [`utf8_error`] method.
 ///
-/// [`Utf8Error`]: core::str::Utf8Error
-/// [`std::str`]: core::str
-/// [`&str`]: prim@str
-/// [`utf8_error`]: Self::utf8_error
+/// [`Utf8Error`]: str::Utf8Error "std::str::Utf8Error"
+/// [`std::str`]: core::str "std::str"
+/// [`&str`]: prim@str "&str"
+/// [`utf8_error`]: FromUtf8Error::utf8_error
 ///
 /// # Examples
 ///
@@ -487,8 +489,8 @@ pub fn from_str(_: &str) -> String {
     /// with this error.
     ///
     /// [`from_utf8_unchecked`]: String::from_utf8_unchecked
-    /// [`Vec<u8>`]: crate::vec::Vec
-    /// [`&str`]: prim@str
+    /// [`Vec<u8>`]: crate::vec::Vec "Vec"
+    /// [`&str`]: prim@str "&str"
     /// [`into_bytes`]: String::into_bytes
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -524,7 +526,7 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
     /// it's already valid UTF-8, we don't need a new allocation. This return
     /// type allows us to handle both cases.
     ///
-    /// [`Cow<'a, str>`]: crate::borrow::Cow
+    /// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
     ///
     /// # Examples
     ///
@@ -625,7 +627,7 @@ pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
     /// conversion requires a memory allocation.
     ///
     /// [`from_utf8_lossy`]: String::from_utf8_lossy
-    /// [`Cow<'a, str>`]: crate::borrow::Cow
+    /// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
     /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
     ///
     /// # Examples
@@ -1721,11 +1723,11 @@ pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
         unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
     }
 
-    /// Converts this `String` into a [`Box`]`<`[`str`]`>`.
+    /// Converts this `String` into a <code>[Box]<[str]></code>.
     ///
     /// This will drop any excess capacity.
     ///
-    /// [`str`]: prim@str
+    /// [str]: prim@str "str"
     ///
     /// # Examples
     ///
@@ -1795,8 +1797,8 @@ pub fn into_bytes(self) -> Vec<u8> {
     /// an analogue to `FromUtf8Error`. See its documentation for more details
     /// on using it.
     ///
-    /// [`std::str`]: core::str
-    /// [`&str`]: prim@str
+    /// [`std::str`]: core::str "std::str"
+    /// [`&str`]: prim@str "&str"
     ///
     /// # Examples
     ///
@@ -2319,7 +2321,7 @@ fn deref_mut(&mut self) -> &mut str {
 ///
 /// This alias exists for backwards compatibility, and may be eventually deprecated.
 ///
-/// [`Infallible`]: core::convert::Infallible
+/// [`Infallible`]: core::convert::Infallible "convert::Infallible"
 #[stable(feature = "str_parse_error", since = "1.5.0")]
 pub type ParseError = core::convert::Infallible;
 
@@ -2606,7 +2608,7 @@ impl<'a> From<&'a str> for Cow<'a, str> {
     /// assert_eq!(Cow::from("eggplant"), Cow::Borrowed("eggplant"));
     /// ```
     ///
-    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed "borrow::Cow::Borrowed"
     #[inline]
     fn from(s: &'a str) -> Cow<'a, str> {
         Cow::Borrowed(s)
@@ -2629,7 +2631,7 @@ impl<'a> From<String> for Cow<'a, str> {
     /// assert_eq!(Cow::from(s), Cow::<'static, str>::Owned(s2));
     /// ```
     ///
-    /// [`Owned`]: crate::borrow::Cow::Owned
+    /// [`Owned`]: crate::borrow::Cow::Owned "borrow::Cow::Owned"
     #[inline]
     fn from(s: String) -> Cow<'a, str> {
         Cow::Owned(s)
@@ -2651,7 +2653,7 @@ impl<'a> From<&'a String> for Cow<'a, str> {
     /// assert_eq!(Cow::from(&s), Cow::Borrowed("eggplant"));
     /// ```
     ///
-    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed "borrow::Cow::Borrowed"
     #[inline]
     fn from(s: &'a String) -> Cow<'a, str> {
         Cow::Borrowed(s.as_str())
index a066e0b49e25c4505381f7d83e037bd8e24e4d86..6e8da849e64cd464baf02714dc9d9f95a9fbaf6f 100644 (file)
@@ -99,8 +99,8 @@ macro_rules! acquire {
 /// first: after all, isn't the point of `Arc<T>` thread safety? The key is
 /// this: `Arc<T>` makes it thread safe to have multiple ownership of the same
 /// data, but it  doesn't add thread safety to its data. Consider
-/// `Arc<`[`RefCell<T>`]`>`. [`RefCell<T>`] isn't [`Sync`], and if `Arc<T>` was always
-/// [`Send`], `Arc<`[`RefCell<T>`]`>` would be as well. But then we'd have a problem:
+/// <code>Arc<[RefCell\<T>]></code>. [`RefCell<T>`] isn't [`Sync`], and if `Arc<T>` was always
+/// [`Send`], <code>Arc<[RefCell\<T>]></code> would be as well. But then we'd have a problem:
 /// [`RefCell<T>`] is not thread safe; it keeps track of the borrowing count using
 /// non-atomic operations.
 ///
@@ -176,6 +176,7 @@ macro_rules! acquire {
 /// [deref]: core::ops::Deref
 /// [downgrade]: Arc::downgrade
 /// [upgrade]: Weak::upgrade
+/// [RefCell\<T>]: core::cell::RefCell
 /// [`RefCell<T>`]: core::cell::RefCell
 /// [`std::sync`]: ../../std/sync/index.html
 /// [`Arc::clone(&from)`]: Arc::clone
@@ -206,7 +207,7 @@ macro_rules! acquire {
 ///
 /// Sharing a mutable [`AtomicUsize`]:
 ///
-/// [`AtomicUsize`]: core::sync::atomic::AtomicUsize
+/// [`AtomicUsize`]: core::sync::atomic::AtomicUsize "sync::atomic::AtomicUsize"
 ///
 /// ```no_run
 /// use std::sync::Arc;
@@ -262,7 +263,7 @@ unsafe fn from_ptr(ptr: *mut ArcInner<T>) -> Self {
 
 /// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
 /// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
-/// pointer, which returns an [`Option`]`<`[`Arc`]`<T>>`.
+/// pointer, which returns an <code>[Option]<[Arc]\<T>></code>.
 ///
 /// Since a `Weak` reference does not count towards ownership, it will not
 /// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no
@@ -476,7 +477,7 @@ pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
     /// assert_eq!(*zero, 0)
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
@@ -684,7 +685,7 @@ pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
     /// assert_eq!(*values, [0, 0, 0])
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
@@ -712,7 +713,7 @@ impl<T> Arc<mem::MaybeUninit<T>> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
@@ -751,7 +752,7 @@ impl<T> Arc<[mem::MaybeUninit<T>]> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
@@ -1086,7 +1087,7 @@ unsafe fn drop_slow(&mut self) {
     /// assert!(!Arc::ptr_eq(&five, &other_five));
     /// ```
     ///
-    /// [`ptr::eq`]: core::ptr::eq
+    /// [`ptr::eq`]: core::ptr::eq "ptr::eq"
     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
         this.ptr.as_ptr() == other.ptr.as_ptr()
     }
@@ -1714,7 +1715,7 @@ impl<T: ?Sized> Weak<T> {
     /// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
     /// ```
     ///
-    /// [`null`]: core::ptr::null
+    /// [`null`]: core::ptr::null "ptr::null"
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(self.ptr);
@@ -1806,7 +1807,6 @@ pub fn into_raw(self) -> *const T {
     /// [`new`]: Weak::new
     /// [`into_raw`]: Weak::into_raw
     /// [`upgrade`]: Weak::upgrade
-    /// [`forget`]: std::mem::forget
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub unsafe fn from_raw(ptr: *const T) -> Self {
         // See Weak::as_ptr for context on how the input pointer is derived.
@@ -1982,7 +1982,7 @@ fn inner(&self) -> Option<WeakInner<'_>> {
     /// assert!(!first.ptr_eq(&third));
     /// ```
     ///
-    /// [`ptr::eq`]: core::ptr::eq
+    /// [`ptr::eq`]: core::ptr::eq "ptr::eq"
     #[inline]
     #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
index cfbf207aee99ced20246b916eed57e43842543cc..c37ec37556157648b9986598487b396c1b709130 100644 (file)
@@ -1,8 +1,8 @@
 //! A contiguous growable array type with heap-allocated contents, written
 //! `Vec<T>`.
 //!
-//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
-//! `O(1)` pop (from the end).
+//! Vectors have *O*(1) indexing, amortized *O*(1) push (to the end) and
+//! *O*(1) pop (from the end).
 //!
 //! Vectors ensure they never allocate more than `isize::MAX` bytes.
 //!
 /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
 /// types inside a `Vec`, it will not allocate space for them. *Note that in this case
 /// the `Vec` might not report a [`capacity`] of 0*. `Vec` will allocate if and only
-/// if [`mem::size_of::<T>`]`() * capacity() > 0`. In general, `Vec`'s allocation
-/// details are very subtle &mdash; if you intend to allocate memory using a `Vec`
+/// if <code>[mem::size_of::\<T>]\() * [capacity]\() > 0</code>. In general, `Vec`'s allocation
+/// details are very subtle --- if you intend to allocate memory using a `Vec`
 /// and use it for something else (either to pass to unsafe code, or to build your
 /// own memory-backed collection), be sure to deallocate this memory by using
 /// `from_raw_parts` to recover the `Vec` and then dropping it.
 /// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
 /// (as defined by the allocator Rust is configured to use by default), and its
 /// pointer points to [`len`] initialized, contiguous elements in order (what
-/// you would see if you coerced it to a slice), followed by [`capacity`]` -
-/// `[`len`] logically uninitialized, contiguous elements.
+/// you would see if you coerced it to a slice), followed by <code>[capacity] - [len]</code>
+/// logically uninitialized, contiguous elements.
 ///
 /// A vector containing the elements `'a'` and `'b'` with capacity 4 can be
 /// visualized as below. The top part is the `Vec` struct, it contains a
 ///
 /// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
 /// sufficient. [`push`] and [`insert`] *will* (re)allocate if
-/// [`len`]` == `[`capacity`]. That is, the reported capacity is completely
+/// <code>[len] == [capacity]</code>. That is, the reported capacity is completely
 /// accurate, and can be relied on. It can even be used to manually free the memory
 /// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
 /// when not necessary.
 ///
 /// `vec![x; n]`, `vec![a, b, c, d]`, and
 /// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`
-/// with exactly the requested capacity. If [`len`]` == `[`capacity`],
+/// with exactly the requested capacity. If <code>[len] == [capacity]</code>,
 /// (as is the case for the [`vec!`] macro), then a `Vec<T>` can be converted to
 /// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements.
 ///
 /// [`&str`]: type@str
 /// [`shrink_to_fit`]: Vec::shrink_to_fit
 /// [`shrink_to`]: Vec::shrink_to
+/// [capacity]: Vec::capacity
 /// [`capacity`]: Vec::capacity
-/// [`mem::size_of::<T>`]: core::mem::size_of
+/// [mem::size_of::\<T>]: core::mem::size_of
+/// [len]: Vec::len
 /// [`len`]: Vec::len
 /// [`push`]: Vec::push
 /// [`insert`]: Vec::insert
@@ -1269,7 +1271,7 @@ pub unsafe fn set_len(&mut self, new_len: usize) {
     ///
     /// The removed element is replaced by the last element of the vector.
     ///
-    /// This does not preserve ordering, but is O(1).
+    /// This does not preserve ordering, but is *O*(1).
     ///
     /// # Panics
     ///
@@ -2842,6 +2844,7 @@ fn from(s: &mut [T]) -> Vec<T> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "vec_from_array", since = "1.44.0")]
 impl<T, const N: usize> From<[T; N]> for Vec<T> {
     #[cfg(not(test))]
index 5767108d423c6c418a6f455ffb1d7a290cf68778..cae4dae708e59cf927a1b10c1e91c78551d3e2fd 100644 (file)
@@ -18,7 +18,6 @@
 #![feature(binary_heap_retain)]
 #![feature(binary_heap_as_slice)]
 #![feature(inplace_iteration)]
-#![feature(iter_map_while)]
 #![feature(slice_group_by)]
 #![feature(slice_partition_dedup)]
 #![feature(vec_spare_capacity)]
index 4780d8dc7883ff0b17ddf2bb32faf32c3aaf230b..0a456ee1eb2d59fde0ac9d7c2b56382ee0a1da1a 100644 (file)
@@ -21,7 +21,7 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct EscapeDefault {
-    range: Range<usize>,
+    range: Range<u8>,
     data: [u8; 4],
 }
 
@@ -114,7 +114,7 @@ fn hexify(b: u8) -> u8 {
 impl Iterator for EscapeDefault {
     type Item = u8;
     fn next(&mut self) -> Option<u8> {
-        self.range.next().map(|i| self.data[i])
+        self.range.next().map(|i| self.data[i as usize])
     }
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.range.size_hint()
@@ -126,7 +126,7 @@ fn last(mut self) -> Option<u8> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl DoubleEndedIterator for EscapeDefault {
     fn next_back(&mut self) -> Option<u8> {
-        self.range.next_back().map(|i| self.data[i])
+        self.range.next_back().map(|i| self.data[i as usize])
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -138,7 +138,9 @@ impl FusedIterator for EscapeDefault {}
 impl fmt::Display for EscapeDefault {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // SAFETY: ok because `escape_default` created only valid utf-8 data
-        f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
+        f.write_str(unsafe {
+            from_utf8_unchecked(&self.data[(self.range.start as usize)..(self.range.end as usize)])
+        })
     }
 }
 
index 166a8e3f28a4190e9adfeda75b90ec29153b8429..3a0c19d7de56f132f5776b061c85601a91e593aa 100644 (file)
@@ -265,6 +265,26 @@ pub struct ArgumentV1<'a> {
     formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
 }
 
+/// This struct represents the unsafety of constructing an `Arguments`.
+/// It exists, rather than an unsafe function, in order to simplify the expansion
+/// of `format_args!(..)` and reduce the scope of the `unsafe` block.
+#[allow(missing_debug_implementations)]
+#[doc(hidden)]
+#[non_exhaustive]
+#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
+pub struct UnsafeArg;
+
+impl UnsafeArg {
+    /// See documentation where `UnsafeArg` is required to know when it is safe to
+    /// create and use `UnsafeArg`.
+    #[doc(hidden)]
+    #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
+    #[inline(always)]
+    pub unsafe fn new() -> Self {
+        Self
+    }
+}
+
 // This guarantees a single stable value for the function pointer associated with
 // indices/counts in the formatting infrastructure.
 //
@@ -337,10 +357,7 @@ impl<'a> Arguments<'a> {
     #[inline]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
     #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
-    pub const unsafe fn new_v1(
-        pieces: &'a [&'static str],
-        args: &'a [ArgumentV1<'a>],
-    ) -> Arguments<'a> {
+    pub const fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
         if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
             panic!("invalid args");
         }
@@ -348,11 +365,29 @@ impl<'a> Arguments<'a> {
     }
 
     /// This function is used to specify nonstandard formatting parameters.
-    /// The `pieces` array must be at least as long as `fmt` to construct
-    /// a valid Arguments structure. Also, any `Count` within `fmt` that is
-    /// `CountIsParam` or `CountIsNextParam` has to point to an argument
-    /// created with `argumentusize`. However, failing to do so doesn't cause
-    /// unsafety, but will ignore invalid .
+    ///
+    /// An `UnsafeArg` is required because the following invariants must be held
+    /// in order for this function to be safe:
+    /// 1. The `pieces` slice must be at least as long as `fmt`.
+    /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a
+    ///    valid index of `args`.
+    /// 3. Every [`Count::Param`] within `fmt` must contain a valid index of
+    ///    `args`.
+    #[cfg(not(bootstrap))]
+    #[doc(hidden)]
+    #[inline]
+    #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
+    #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
+    pub const fn new_v1_formatted(
+        pieces: &'a [&'static str],
+        args: &'a [ArgumentV1<'a>],
+        fmt: &'a [rt::v1::Argument],
+        _unsafe_arg: UnsafeArg,
+    ) -> Arguments<'a> {
+        Arguments { pieces, fmt: Some(fmt), args }
+    }
+
+    #[cfg(bootstrap)]
     #[doc(hidden)]
     #[inline]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
@@ -1189,7 +1224,7 @@ unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize
 
 /// Padding after the end of something. Returned by `Formatter::padding`.
 #[must_use = "don't forget to write the post padding"]
-struct PostPadding {
+pub(crate) struct PostPadding {
     fill: char,
     padding: usize,
 }
@@ -1200,9 +1235,9 @@ fn new(fill: char, padding: usize) -> PostPadding {
     }
 
     /// Write this post padding.
-    fn write(self, buf: &mut dyn Write) -> Result {
+    pub(crate) fn write(self, f: &mut Formatter<'_>) -> Result {
         for _ in 0..self.padding {
-            buf.write_char(self.fill)?;
+            f.buf.write_char(self.fill)?;
         }
         Ok(())
     }
@@ -1325,7 +1360,7 @@ fn write_prefix(f: &mut Formatter<'_>, sign: Option<char>, prefix: Option<&str>)
                 write_prefix(self, sign, prefix)?;
                 let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
                 self.buf.write_str(buf)?;
-                post_padding.write(self.buf)?;
+                post_padding.write(self)?;
                 self.fill = old_fill;
                 self.align = old_align;
                 Ok(())
@@ -1335,7 +1370,7 @@ fn write_prefix(f: &mut Formatter<'_>, sign: Option<char>, prefix: Option<&str>)
                 let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
                 write_prefix(self, sign, prefix)?;
                 self.buf.write_str(buf)?;
-                post_padding.write(self.buf)
+                post_padding.write(self)
             }
         }
     }
@@ -1410,7 +1445,7 @@ pub fn pad(&mut self, s: &str) -> Result {
                     let align = rt::v1::Alignment::Left;
                     let post_padding = self.padding(width - chars_count, align)?;
                     self.buf.write_str(s)?;
-                    post_padding.write(self.buf)
+                    post_padding.write(self)
                 }
             }
         }
@@ -1419,7 +1454,7 @@ pub fn pad(&mut self, s: &str) -> Result {
     /// Write the pre-padding and return the unwritten post-padding. Callers are
     /// responsible for ensuring post-padding is written after the thing that is
     /// being padded.
-    fn padding(
+    pub(crate) fn padding(
         &mut self,
         padding: usize,
         default: rt::v1::Alignment,
@@ -1474,7 +1509,7 @@ fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
             } else {
                 let post_padding = self.padding(width - len, align)?;
                 self.write_formatted_parts(&formatted)?;
-                post_padding.write(self.buf)
+                post_padding.write(self)
             };
             self.fill = old_fill;
             self.align = old_align;
index 8f89e1588048ffd07dbaf7d573e64aa38ebbed51..793b05fcf9529da6f7465bca7dbdf9f6e13e80c4 100644 (file)
@@ -10,7 +10,7 @@
 /// [`map_while`]: Iterator::map_while
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[stable(feature = "iter_map_while", since = "1.57.0")]
 #[derive(Clone)]
 pub struct MapWhile<I, P> {
     iter: I,
@@ -23,14 +23,14 @@ pub(in crate::iter) fn new(iter: I, predicate: P) -> MapWhile<I, P> {
     }
 }
 
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[stable(feature = "iter_map_while", since = "1.57.0")]
 impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("MapWhile").field("iter", &self.iter).finish()
     }
 }
 
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[stable(feature = "iter_map_while", since = "1.57.0")]
 impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
 where
     P: FnMut(I::Item) -> Option<B>,
index f02d278aff5e4b980375a4000737a426d6f6e0a3..48e7dcfa7d9a30d838c275233a0f95f7645bb208 100644 (file)
@@ -45,7 +45,7 @@
 #[stable(feature = "iter_intersperse", since = "1.56.0")]
 pub use self::intersperse::{Intersperse, IntersperseWith};
 
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[stable(feature = "iter_map_while", since = "1.57.0")]
 pub use self::map_while::MapWhile;
 
 #[unstable(feature = "trusted_random_access", issue = "none")]
index cd8a26025ffb6291543288cf0a859f034a93dc7a..39c0b1b522c11fbe79fc33b296387a3de135b525 100644 (file)
@@ -39,7 +39,7 @@
 //! ```
 //!
 //! An iterator has a method, [`next`], which when called, returns an
-//! [`Option`]`<Item>`. [`next`] will return [`Some(Item)`] as long as there
+//! <code>[Option]\<Item></code>. Calling [`next`] will return [`Some(Item)`] as long as there
 //! are elements, and once they've all been exhausted, will return `None` to
 //! indicate that iteration is finished. Individual iterators may choose to
 //! resume iteration, and so calling [`next`] again may or may not eventually
 pub use self::adapters::Copied;
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 pub use self::adapters::Flatten;
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[stable(feature = "iter_map_while", since = "1.57.0")]
 pub use self::adapters::MapWhile;
 #[unstable(feature = "inplace_iteration", issue = "none")]
 pub use self::adapters::SourceIter;
index b0a9d9f5ef5c9c6f192bf097cae32984d267e3bc..f2336fb2865b09edba5660d34399d6c3150a2926 100644 (file)
@@ -96,7 +96,7 @@ pub trait Iterator {
     /// Specifically, `size_hint()` returns a tuple where the first element
     /// is the lower bound, and the second element is the upper bound.
     ///
-    /// The second half of the tuple that is returned is an [`Option`]`<`[`usize`]`>`.
+    /// The second half of the tuple that is returned is an <code>[Option]<[usize]></code>.
     /// A [`None`] here means that either there is no known upper bound, or the
     /// upper bound is larger than [`usize`].
     ///
@@ -115,11 +115,9 @@ pub trait Iterator {
     /// That said, the implementation should provide a correct estimation,
     /// because otherwise it would be a violation of the trait's protocol.
     ///
-    /// The default implementation returns `(0, `[`None`]`)` which is correct for any
+    /// The default implementation returns <code>(0, [None])</code> which is correct for any
     /// iterator.
     ///
-    /// [`usize`]: type@usize
-    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -864,7 +862,6 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
     /// The returned iterator might panic if the to-be-returned index would
     /// overflow a [`usize`].
     ///
-    /// [`usize`]: type@usize
     /// [`zip`]: Iterator::zip
     ///
     /// # Examples
@@ -1116,7 +1113,6 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_map_while)]
     /// let a = [-1i32, 4, 0, 1];
     ///
     /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));
@@ -1147,7 +1143,6 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     /// Stopping after an initial [`None`]:
     ///
     /// ```
-    /// #![feature(iter_map_while)]
     /// use std::convert::TryFrom;
     ///
     /// let a = [0, 1, 2, -3, 4, 5, -6];
@@ -1165,7 +1160,6 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     /// removed:
     ///
     /// ```
-    /// #![feature(iter_map_while)]
     /// use std::convert::TryFrom;
     ///
     /// let a = [1, 2, -3, 4];
@@ -1191,7 +1185,7 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     ///
     /// [`fuse`]: Iterator::fuse
     #[inline]
-    #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+    #[stable(feature = "iter_map_while", since = "1.57.0")]
     fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
     where
         Self: Sized,
@@ -1801,10 +1795,11 @@ fn extend<'a, T, B: Extend<T>>(
     /// The relative order of partitioned items is not maintained.
     ///
     /// # Current implementation
+    ///
     /// Current algorithms tries finding the first element for which the predicate evaluates
     /// to false, and the last element for which it evaluates to true and repeatedly swaps them.
     ///
-    /// Time Complexity: *O*(*N*)
+    /// Time complexity: *O*(*n*)
     ///
     /// See also [`is_partitioned()`] and [`partition()`].
     ///
index 2a02545041dcf7397f6020314b251167840de50f..daef5c98967cc4cfe1ca9058da04ff97725a25f3 100644 (file)
@@ -1849,17 +1849,17 @@ pub const fn rem_euclid(self, rhs: Self) -> Self {
         #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
         /// let b = 3;
         ///
-        /// assert_eq!(a.div_floor(b), 2);
-        /// assert_eq!(a.div_floor(-b), -3);
-        /// assert_eq!((-a).div_floor(b), -3);
-        /// assert_eq!((-a).div_floor(-b), 2);
+        /// assert_eq!(a.unstable_div_floor(b), 2);
+        /// assert_eq!(a.unstable_div_floor(-b), -3);
+        /// assert_eq!((-a).unstable_div_floor(b), -3);
+        /// assert_eq!((-a).unstable_div_floor(-b), 2);
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        pub const fn div_floor(self, rhs: Self) -> Self {
+        pub const fn unstable_div_floor(self, rhs: Self) -> Self {
             let d = self / rhs;
             let r = self % rhs;
             if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
@@ -1884,17 +1884,17 @@ pub const fn div_floor(self, rhs: Self) -> Self {
         #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
         /// let b = 3;
         ///
-        /// assert_eq!(a.div_ceil(b), 3);
-        /// assert_eq!(a.div_ceil(-b), -2);
-        /// assert_eq!((-a).div_ceil(b), -2);
-        /// assert_eq!((-a).div_ceil(-b), 3);
+        /// assert_eq!(a.unstable_div_ceil(b), 3);
+        /// assert_eq!(a.unstable_div_ceil(-b), -2);
+        /// assert_eq!((-a).unstable_div_ceil(b), -2);
+        /// assert_eq!((-a).unstable_div_ceil(-b), 3);
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        pub const fn div_ceil(self, rhs: Self) -> Self {
+        pub const fn unstable_div_ceil(self, rhs: Self) -> Self {
             let d = self / rhs;
             let r = self % rhs;
             if (r > 0 && rhs > 0) || (r < 0 && rhs < 0) {
@@ -1919,21 +1919,21 @@ pub const fn div_ceil(self, rhs: Self) -> Self {
         ///
         /// ```
         /// #![feature(int_roundings)]
-        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
-        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(8), 24);")]
-        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(-8), 16);")]
-        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(-8), 16);")]
-        #[doc = concat!("assert_eq!((-16_", stringify!($SelfT), ").next_multiple_of(8), -16);")]
-        #[doc = concat!("assert_eq!((-23_", stringify!($SelfT), ").next_multiple_of(8), -16);")]
-        #[doc = concat!("assert_eq!((-16_", stringify!($SelfT), ").next_multiple_of(-8), -16);")]
-        #[doc = concat!("assert_eq!((-23_", stringify!($SelfT), ").next_multiple_of(-8), -24);")]
+        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".unstable_next_multiple_of(8), 16);")]
+        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".unstable_next_multiple_of(8), 24);")]
+        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".unstable_next_multiple_of(-8), 16);")]
+        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".unstable_next_multiple_of(-8), 16);")]
+        #[doc = concat!("assert_eq!((-16_", stringify!($SelfT), ").unstable_next_multiple_of(8), -16);")]
+        #[doc = concat!("assert_eq!((-23_", stringify!($SelfT), ").unstable_next_multiple_of(8), -16);")]
+        #[doc = concat!("assert_eq!((-16_", stringify!($SelfT), ").unstable_next_multiple_of(-8), -16);")]
+        #[doc = concat!("assert_eq!((-23_", stringify!($SelfT), ").unstable_next_multiple_of(-8), -24);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        pub const fn next_multiple_of(self, rhs: Self) -> Self {
+        pub const fn unstable_next_multiple_of(self, rhs: Self) -> Self {
             // This would otherwise fail when calculating `r` when self == T::MIN.
             if rhs == -1 {
                 return self;
index 7523d8ec976ddd137c9d9ba366f96d6504e22106..8ce826626309147f7c2ace97f2ca3f975cd8305e 100644 (file)
@@ -1859,12 +1859,12 @@ pub const fn rem_euclid(self, rhs: Self) -> Self {
         ///
         /// ```
         /// #![feature(int_roundings)]
-        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_floor(4), 1);")]
+        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_floor(4), 1);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[inline(always)]
         #[rustc_inherit_overflow_checks]
-        pub const fn div_floor(self, rhs: Self) -> Self {
+        pub const fn unstable_div_floor(self, rhs: Self) -> Self {
             self / rhs
         }
 
@@ -1880,12 +1880,12 @@ pub const fn div_floor(self, rhs: Self) -> Self {
         ///
         /// ```
         /// #![feature(int_roundings)]
-        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_ceil(4), 2);")]
+        #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_ceil(4), 2);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        pub const fn div_ceil(self, rhs: Self) -> Self {
+        pub const fn unstable_div_ceil(self, rhs: Self) -> Self {
             let d = self / rhs;
             let r = self % rhs;
             if r > 0 && rhs > 0 {
@@ -1908,15 +1908,15 @@ pub const fn div_ceil(self, rhs: Self) -> Self {
         ///
         /// ```
         /// #![feature(int_roundings)]
-        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
-        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(8), 24);")]
+        #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".unstable_next_multiple_of(8), 16);")]
+        #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".unstable_next_multiple_of(8), 24);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
-        pub const fn next_multiple_of(self, rhs: Self) -> Self {
+        pub const fn unstable_next_multiple_of(self, rhs: Self) -> Self {
             match self % rhs {
                 0 => self,
                 r => self + (rhs - r)
index 907726f0c345c8a3736cbae493697e861aba609c..94d892dd787a6874579ae7db1e405a5a1efbfcc6 100644 (file)
@@ -47,9 +47,9 @@
 //!
 //! Rust's pointer types must always point to a valid location; there are
 //! no "null" references. Instead, Rust has *optional* pointers, like
-//! the optional owned box, [`Option`]`<`[`Box<T>`]`>`.
+//! the optional owned box, <code>[Option]<[Box\<T>]></code>.
 //!
-//! [`Box<T>`]: ../../std/boxed/struct.Box.html
+//! [Box\<T>]: ../../std/boxed/struct.Box.html
 //!
 //! The following example uses [`Option`] to create an optional box of
 //! [`i32`]. Notice that in order to use the inner [`i32`] value, the
 //!
 //! ## Adapters for working with references
 //!
-//! * [`as_ref`] converts from `&Option<T>` to `Option<&T>`
-//! * [`as_mut`] converts from `&mut Option<T>` to `Option<&mut T>`
-//! * [`as_deref`] converts from `&Option<T>` to `Option<&T::Target>`
-//! * [`as_deref_mut`] converts from `&mut Option<T>` to
-//!   `Option<&mut T::Target>`
-//! * [`as_pin_ref`] converts from [`Pin`]`<&Option<T>>` to
-//!   `Option<`[`Pin`]`<&T>>`
-//! * [`as_pin_mut`] converts from [`Pin`]`<&mut Option<T>>` to
-//!   `Option<`[`Pin`]`<&mut T>>`
-//!
+//! * [`as_ref`] converts from <code>[&][][Option]\<T></code> to <code>[Option]<[&]T></code>
+//! * [`as_mut`] converts from <code>[&mut] [Option]\<T></code> to <code>[Option]<[&mut] T></code>
+//! * [`as_deref`] converts from <code>[&][][Option]\<T></code> to
+//!   <code>[Option]<[&]T::[Target]></code>
+//! * [`as_deref_mut`] converts from <code>[&mut] [Option]\<T></code> to
+//!   <code>[Option]<[&mut] T::[Target]></code>
+//! * [`as_pin_ref`] converts from <code>[Pin]<[&][][Option]\<T>></code> to
+//!   <code>[Option]<[Pin]<[&]T>></code>
+//! * [`as_pin_mut`] converts from <code>[Pin]<[&mut] [Option]\<T>></code> to
+//!   <code>[Option]<[Pin]<[&mut] T>></code>
+//!
+//! [&]: reference "shared reference"
+//! [&mut]: reference "mutable reference"
+//! [Target]: Deref::Target "ops::Deref::Target"
 //! [`as_deref`]: Option::as_deref
 //! [`as_deref_mut`]: Option::as_deref_mut
 //! [`as_mut`]: Option::as_mut
@@ -603,13 +607,13 @@ pub fn contains<U>(&self, x: &U) -> bool
     ///
     /// # Examples
     ///
-    /// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, preserving the original.
-    /// The [`map`] method takes the `self` argument by value, consuming the original,
+    /// Converts an <code>Option<[String]></code> into an <code>Option<[usize]></code>, preserving
+    /// the original. The [`map`] method takes the `self` argument by value, consuming the original,
     /// so this technique uses `as_ref` to first take an `Option` to a reference
     /// to the value inside the original.
     ///
     /// [`map`]: Option::map
-    /// [`String`]: ../../std/string/struct.String.html
+    /// [String]: ../../std/string/struct.String.html "String"
     ///
     /// ```
     /// let text: Option<String> = Some("Hello, world!".to_string());
@@ -649,7 +653,9 @@ pub fn as_mut(&mut self) -> Option<&mut T> {
         }
     }
 
-    /// Converts from [`Pin`]`<&Option<T>>` to `Option<`[`Pin`]`<&T>>`.
+    /// Converts from <code>[Pin]<[&]Option\<T>></code> to <code>Option<[Pin]<[&]T>></code>.
+    ///
+    /// [&]: reference "shared reference"
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
@@ -658,7 +664,9 @@ pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
         unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
     }
 
-    /// Converts from [`Pin`]`<&mut Option<T>>` to `Option<`[`Pin`]`<&mut T>>`.
+    /// Converts from <code>[Pin]<[&mut] Option\<T>></code> to <code>Option<[Pin]<[&mut] T>></code>.
+    ///
+    /// [&mut]: reference "mutable reference"
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
@@ -819,9 +827,10 @@ pub unsafe fn unwrap_unchecked(self) -> T {
     ///
     /// # Examples
     ///
-    /// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, consuming the original:
+    /// Converts an <code>Option<[String]></code> into an <code>Option<[usize]></code>, consuming
+    /// the original:
     ///
-    /// [`String`]: ../../std/string/struct.String.html
+    /// [String]: ../../std/string/struct.String.html "String"
     /// ```
     /// let maybe_some_string = Some(String::from("Hello, World!"));
     /// // `Option::map` takes self *by value*, consuming `maybe_some_string`
@@ -1581,9 +1590,9 @@ pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
 impl<T, E> Option<Result<T, E>> {
     /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`.
     ///
-    /// [`None`] will be mapped to [`Ok`]`(`[`None`]`)`.
-    /// [`Some`]`(`[`Ok`]`(_))` and [`Some`]`(`[`Err`]`(_))` will be mapped to
-    /// [`Ok`]`(`[`Some`]`(_))` and [`Err`]`(_)`.
+    /// [`None`] will be mapped to <code>[Ok]\([None])</code>.
+    /// <code>[Some]\([Ok]\(\_))</code> and <code>[Some]\([Err]\(\_))</code> will be mapped to
+    /// <code>[Ok]\([Some]\(\_))</code> and <code>[Err]\(\_)</code>.
     ///
     /// # Examples
     ///
@@ -1721,13 +1730,13 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
     ///
     /// # Examples
     ///
-    /// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, preserving the original.
-    /// The [`map`] method takes the `self` argument by value, consuming the original,
-    /// so this technique uses `from` to first take an `Option` to a reference
+    /// Converts an <code>[Option]<[String]></code> into an <code>[Option]<[usize]></code>, preserving
+    /// the original. The [`map`] method takes the `self` argument by value, consuming the original,
+    /// so this technique uses `from` to first take an [`Option`] to a reference
     /// to the value inside the original.
     ///
     /// [`map`]: Option::map
-    /// [`String`]: ../../std/string/struct.String.html
+    /// [String]: ../../std/string/struct.String.html "String"
     ///
     /// ```
     /// let s: Option<String> = Some(String::from("Hello, Rustaceans!"));
index a6aa4bf43c865292e1764a6a6fa3a02826db2ae3..6d3ec6ae8612a109987df7a91c59d319bdbe8fcd 100644 (file)
@@ -47,10 +47,7 @@ pub fn panic(expr: &'static str) -> ! {
     // truncation and padding (even though none is used here). Using
     // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
     // output binary, saving up to a few kilobytes.
-    panic_fmt(
-        // SAFETY: Arguments::new_v1 is safe with exactly one str and zero args
-        unsafe { fmt::Arguments::new_v1(&[expr], &[]) },
-    );
+    panic_fmt(fmt::Arguments::new_v1(&[expr], &[]));
 }
 
 #[inline]
index 6a1a84bafa330acd0d0aec5d4eb13c6f1df7e623..8b645792169155aba160c46382db7721b776265c 100644 (file)
 //! [Vec::push]: ../../std/vec/struct.Vec.html#method.push "Vec::push"
 //! [Rc]: ../../std/rc/struct.Rc.html "rc::Rc"
 //! [RefCell]: crate::cell::RefCell "cell::RefCell"
-//! [`drop`]: Drop::drop "Drop::drop"
+//! [`drop`]: Drop::drop
 //! [VecDeque]: ../../std/collections/struct.VecDeque.html "collections::VecDeque"
 //! [`ptr::write`]: crate::ptr::write "ptr::write"
 //! [`Future`]: crate::future::Future "future::Future"
 //! [drop-impl]: #drop-implementation
 //! [drop-guarantee]: #drop-guarantee
 //! [`poll`]: crate::future::Future::poll "future::Future::poll"
-//! [&]: ../../std/primitive.reference.html "shared reference"
-//! [&mut]: ../../std/primitive.reference.html "mutable reference"
+//! [&]: reference "shared reference"
+//! [&mut]: reference "mutable reference"
 //! [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe"
 
 #![stable(feature = "pin", since = "1.33.0")]
index 092e6544342b7f4e2105ce21fd9b81d25d29bede..4a300f857e9ed9dd4623ca07c983dc6f0f5b6cb5 100644 (file)
@@ -88,7 +88,7 @@
 //! ```
 //!
 //! *Note: The actual definition of [`Write`] uses [`io::Result`], which
-//! is just a synonym for [`Result`]`<T, `[`io::Error`]`>`.*
+//! is just a synonym for <code>[Result]<T, [io::Error]></code>.*
 //!
 //! This method doesn't produce a value, but the write may
 //! fail. It's crucial to handle the error case, and *not* write
 //! early return of [`Err`] that it provides.
 //!
 //! [`expect`]: Result::expect
-//! [`Write`]: ../../std/io/trait.Write.html
-//! [`write_all`]: ../../std/io/trait.Write.html#method.write_all
-//! [`io::Result`]: ../../std/io/type.Result.html
+//! [`Write`]: ../../std/io/trait.Write.html "io::Write"
+//! [`write_all`]: ../../std/io/trait.Write.html#method.write_all "io::Write::write_all"
+//! [`io::Result`]: ../../std/io/type.Result.html "io::Result"
 //! [`?`]: crate::ops::Try
 //! [`Ok(T)`]: Ok
 //! [`Err(E)`]: Err
-//! [`io::Error`]: ../../std/io/struct.Error.html
+//! [io::Error]: ../../std/io/struct.Error.html "io::Error"
 //!
 //! # Method overview
 //!
index e37902dae1f2d24de0e5f0752ab2f7b7a5d723f0..d102619b8e5ec135f09090ae7b1e08e5413c3a87 100644 (file)
@@ -52,7 +52,7 @@ pub trait Stream {
     /// Specifically, `size_hint()` returns a tuple where the first element
     /// is the lower bound, and the second element is the upper bound.
     ///
-    /// The second half of the tuple that is returned is an [`Option`]`<`[`usize`]`>`.
+    /// The second half of the tuple that is returned is an <code>[Option]<[usize]></code>.
     /// A [`None`] here means that either there is no known upper bound, or the
     /// upper bound is larger than [`usize`].
     ///
@@ -71,7 +71,7 @@ pub trait Stream {
     /// That said, the implementation should provide a correct estimation,
     /// because otherwise it would be a violation of the trait's protocol.
     ///
-    /// The default implementation returns `(0, `[`None`]`)` which is correct for any
+    /// The default implementation returns <code>(0, [None])</code> which is correct for any
     /// stream.
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
index 250704609963217e62828be3ae43c2a1f7eaca10..57416aeb7018fe5712b958018a17cf32a0d0fca4 100644 (file)
@@ -30,9 +30,10 @@ impl<T> Poll<T> {
     ///
     /// # Examples
     ///
-    /// Converts a `Poll<`[`String`]`>` into an `Poll<`[`usize`]`>`, consuming the original:
+    /// Converts a <code>Poll<[String]></code> into a <code>Poll<[usize]></code>, consuming
+    /// the original:
     ///
-    /// [`String`]: ../../std/string/struct.String.html
+    /// [String]: ../../std/string/struct.String.html "String"
     /// ```
     /// # use core::task::Poll;
     /// let poll_some_string = Poll::Ready(String::from("Hello, World!"));
index 35b740cd74372b9a03a1343bf9445c01d7cb9a5a..d1533b8d67a6bf97e1f3360dc3661bd7fcfd96c0 100644 (file)
@@ -1049,11 +1049,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         /// `divisor` must not be above 100_000_000. It also should be a power
         /// of 10, everything else doesn't make sense. `fractional_part` has
         /// to be less than `10 * divisor`!
+        ///
+        /// A prefix and postfix may be added. The whole thing is padded
+        /// to the formatter's `width`, if specified.
         fn fmt_decimal(
             f: &mut fmt::Formatter<'_>,
             mut integer_part: u64,
             mut fractional_part: u32,
             mut divisor: u32,
+            prefix: &str,
+            postfix: &str,
         ) -> fmt::Result {
             // Encode the fractional part into a temporary buffer. The buffer
             // only need to hold 9 elements, because `fractional_part` has to
@@ -1114,48 +1119,91 @@ fn fmt_decimal(
             // set, we only use all digits up to the last non-zero one.
             let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
 
-            // If we haven't emitted a single fractional digit and the precision
-            // wasn't set to a non-zero value, we don't print the decimal point.
-            if end == 0 {
-                write!(f, "{}", integer_part)
-            } else {
-                // SAFETY: We are only writing ASCII digits into the buffer and it was
-                // initialized with '0's, so it contains valid UTF8.
-                let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
+            // This closure emits the formatted duration without emitting any
+            // padding (padding is calculated below).
+            let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
+                write!(f, "{}{}", prefix, integer_part)?;
+
+                // Write the decimal point and the fractional part (if any).
+                if end > 0 {
+                    // SAFETY: We are only writing ASCII digits into the buffer and
+                    // it was initialized with '0's, so it contains valid UTF8.
+                    let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
+
+                    // If the user request a precision > 9, we pad '0's at the end.
+                    let w = f.precision().unwrap_or(pos);
+                    write!(f, ".{:0<width$}", s, width = w)?;
+                }
 
-                // If the user request a precision > 9, we pad '0's at the end.
-                let w = f.precision().unwrap_or(pos);
-                write!(f, "{}.{:0<width$}", integer_part, s, width = w)
+                write!(f, "{}", postfix)
+            };
+
+            match f.width() {
+                None => {
+                    // No `width` specified. There's no need to calculate the
+                    // length of the output in this case, just emit it.
+                    emit_without_padding(f)
+                }
+                Some(requested_w) => {
+                    // A `width` was specified. Calculate the actual width of
+                    // the output in order to calculate the required padding.
+                    // It consists of 4 parts:
+                    // 1. The prefix: is either "+" or "", so we can just use len().
+                    // 2. The postfix: can be "µs" so we have to count UTF8 characters.
+                    let mut actual_w = prefix.len() + postfix.chars().count();
+                    // 3. The integer part:
+                    if let Some(log) = integer_part.checked_log10() {
+                        // integer_part is > 0, so has length log10(x)+1
+                        actual_w += 1 + log as usize;
+                    } else {
+                        // integer_part is 0, so has length 1.
+                        actual_w += 1;
+                    }
+                    // 4. The fractional part (if any):
+                    if end > 0 {
+                        let frac_part_w = f.precision().unwrap_or(pos);
+                        actual_w += 1 + frac_part_w;
+                    }
+
+                    if requested_w <= actual_w {
+                        // Output is already longer than `width`, so don't pad.
+                        emit_without_padding(f)
+                    } else {
+                        // We need to add padding. Use the `Formatter::padding` helper function.
+                        let default_align = crate::fmt::rt::v1::Alignment::Left;
+                        let post_padding = f.padding(requested_w - actual_w, default_align)?;
+                        emit_without_padding(f)?;
+                        post_padding.write(f)
+                    }
+                }
             }
         }
 
         // Print leading '+' sign if requested
-        if f.sign_plus() {
-            write!(f, "+")?;
-        }
+        let prefix = if f.sign_plus() { "+" } else { "" };
 
         if self.secs > 0 {
-            fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10)?;
-            f.write_str("s")
+            fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10, prefix, "s")
         } else if self.nanos >= NANOS_PER_MILLI {
             fmt_decimal(
                 f,
                 (self.nanos / NANOS_PER_MILLI) as u64,
                 self.nanos % NANOS_PER_MILLI,
                 NANOS_PER_MILLI / 10,
-            )?;
-            f.write_str("ms")
+                prefix,
+                "ms",
+            )
         } else if self.nanos >= NANOS_PER_MICRO {
             fmt_decimal(
                 f,
                 (self.nanos / NANOS_PER_MICRO) as u64,
                 self.nanos % NANOS_PER_MICRO,
                 NANOS_PER_MICRO / 10,
-            )?;
-            f.write_str("µs")
+                prefix,
+                "µs",
+            )
         } else {
-            fmt_decimal(f, self.nanos as u64, 0, 1)?;
-            f.write_str("ns")
+            fmt_decimal(f, self.nanos as u64, 0, 1, prefix, "ns")
         }
     }
 }
index 19bcc45108dfd5225761723e0c6b7bb64fbb0eaa..cd3aed4cd28f81a7d90c9f7fc15cfb2a99d97d19 100644 (file)
@@ -50,7 +50,6 @@
 #![feature(iter_partition_in_place)]
 #![feature(iter_is_partitioned)]
 #![feature(iter_order_by)]
-#![feature(iter_map_while)]
 #![feature(const_mut_refs)]
 #![feature(const_pin)]
 #![feature(const_slice_from_raw_parts)]
index d2d655ea2c75015959b518a695d6b4dd8f63240a..0ad85bf6d943d1d254ef0f34a0d0a348b8b0108c 100644 (file)
@@ -294,33 +294,33 @@ fn test_pow() {
             fn test_div_floor() {
                 let a: $T = 8;
                 let b = 3;
-                assert_eq!(a.div_floor(b), 2);
-                assert_eq!(a.div_floor(-b), -3);
-                assert_eq!((-a).div_floor(b), -3);
-                assert_eq!((-a).div_floor(-b), 2);
+                assert_eq!(a.unstable_div_floor(b), 2);
+                assert_eq!(a.unstable_div_floor(-b), -3);
+                assert_eq!((-a).unstable_div_floor(b), -3);
+                assert_eq!((-a).unstable_div_floor(-b), 2);
             }
 
             #[test]
             fn test_div_ceil() {
                 let a: $T = 8;
                 let b = 3;
-                assert_eq!(a.div_ceil(b), 3);
-                assert_eq!(a.div_ceil(-b), -2);
-                assert_eq!((-a).div_ceil(b), -2);
-                assert_eq!((-a).div_ceil(-b), 3);
+                assert_eq!(a.unstable_div_ceil(b), 3);
+                assert_eq!(a.unstable_div_ceil(-b), -2);
+                assert_eq!((-a).unstable_div_ceil(b), -2);
+                assert_eq!((-a).unstable_div_ceil(-b), 3);
             }
 
             #[test]
             fn test_next_multiple_of() {
-                assert_eq!((16 as $T).next_multiple_of(8), 16);
-                assert_eq!((23 as $T).next_multiple_of(8), 24);
-                assert_eq!((16 as $T).next_multiple_of(-8), 16);
-                assert_eq!((23 as $T).next_multiple_of(-8), 16);
-                assert_eq!((-16 as $T).next_multiple_of(8), -16);
-                assert_eq!((-23 as $T).next_multiple_of(8), -16);
-                assert_eq!((-16 as $T).next_multiple_of(-8), -16);
-                assert_eq!((-23 as $T).next_multiple_of(-8), -24);
-                assert_eq!(MIN.next_multiple_of(-1), MIN);
+                assert_eq!((16 as $T).unstable_next_multiple_of(8), 16);
+                assert_eq!((23 as $T).unstable_next_multiple_of(8), 24);
+                assert_eq!((16 as $T).unstable_next_multiple_of(-8), 16);
+                assert_eq!((23 as $T).unstable_next_multiple_of(-8), 16);
+                assert_eq!((-16 as $T).unstable_next_multiple_of(8), -16);
+                assert_eq!((-23 as $T).unstable_next_multiple_of(8), -16);
+                assert_eq!((-16 as $T).unstable_next_multiple_of(-8), -16);
+                assert_eq!((-23 as $T).unstable_next_multiple_of(-8), -24);
+                assert_eq!(MIN.unstable_next_multiple_of(-1), MIN);
             }
 
             #[test]
index 49f8f1f13fad46ffc0a79fd228b5e4f8bbf0f5e2..35ec88c6af7d6873396354bed9154eb2732310f7 100644 (file)
@@ -208,19 +208,19 @@ fn test_pow() {
 
             #[test]
             fn test_div_floor() {
-                assert_eq!((8 as $T).div_floor(3), 2);
+                assert_eq!((8 as $T).unstable_div_floor(3), 2);
             }
 
             #[test]
             fn test_div_ceil() {
-                assert_eq!((8 as $T).div_ceil(3), 3);
+                assert_eq!((8 as $T).unstable_div_ceil(3), 3);
             }
 
             #[test]
             fn test_next_multiple_of() {
-                assert_eq!((16 as $T).next_multiple_of(8), 16);
-                assert_eq!((23 as $T).next_multiple_of(8), 24);
-                assert_eq!(MAX.next_multiple_of(1), MAX);
+                assert_eq!((16 as $T).unstable_next_multiple_of(8), 16);
+                assert_eq!((23 as $T).unstable_next_multiple_of(8), 24);
+                assert_eq!(MAX.unstable_next_multiple_of(1), MAX);
             }
 
             #[test]
index f14639e0d589fb95eeb5abc329ad0a9eba461d92..fe2d2f2412daa1fe79357396d0fb712f32eba761 100644 (file)
@@ -313,6 +313,34 @@ fn debug_formatting_precision_two() {
     assert_eq!(format!("{:.2?}", Duration::new(8, 999_999_999)), "9.00s");
 }
 
+#[test]
+fn debug_formatting_padding() {
+    assert_eq!("0ns      ", format!("{:<9?}", Duration::new(0, 0)));
+    assert_eq!("      0ns", format!("{:>9?}", Duration::new(0, 0)));
+    assert_eq!("   0ns   ", format!("{:^9?}", Duration::new(0, 0)));
+    assert_eq!("123ns    ", format!("{:<9.0?}", Duration::new(0, 123)));
+    assert_eq!("    123ns", format!("{:>9.0?}", Duration::new(0, 123)));
+    assert_eq!("  123ns  ", format!("{:^9.0?}", Duration::new(0, 123)));
+    assert_eq!("123.0ns  ", format!("{:<9.1?}", Duration::new(0, 123)));
+    assert_eq!("  123.0ns", format!("{:>9.1?}", Duration::new(0, 123)));
+    assert_eq!(" 123.0ns ", format!("{:^9.1?}", Duration::new(0, 123)));
+    assert_eq!("7.1µs    ", format!("{:<9?}", Duration::new(0, 7_100)));
+    assert_eq!("    7.1µs", format!("{:>9?}", Duration::new(0, 7_100)));
+    assert_eq!("  7.1µs  ", format!("{:^9?}", Duration::new(0, 7_100)));
+    assert_eq!("999.123456ms", format!("{:<9?}", Duration::new(0, 999_123_456)));
+    assert_eq!("999.123456ms", format!("{:>9?}", Duration::new(0, 999_123_456)));
+    assert_eq!("999.123456ms", format!("{:^9?}", Duration::new(0, 999_123_456)));
+    assert_eq!("5s       ", format!("{:<9?}", Duration::new(5, 0)));
+    assert_eq!("       5s", format!("{:>9?}", Duration::new(5, 0)));
+    assert_eq!("   5s    ", format!("{:^9?}", Duration::new(5, 0)));
+    assert_eq!("5.000000000000s", format!("{:<9.12?}", Duration::new(5, 0)));
+    assert_eq!("5.000000000000s", format!("{:>9.12?}", Duration::new(5, 0)));
+    assert_eq!("5.000000000000s", format!("{:^9.12?}", Duration::new(5, 0)));
+
+    // default alignment is left:
+    assert_eq!("5s       ", format!("{:9?}", Duration::new(5, 0)));
+}
+
 #[test]
 fn debug_formatting_precision_high() {
     assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs");
index 1b051b0d0f6e5079802b5bf394152ab5284901b5..2b77dc54ab35cd3ccece5d7f37d2e85632c92177 100644 (file)
@@ -72,6 +72,7 @@ panic_immediate_abort = ["core/panic_immediate_abort"]
 # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
 std_detect_file_io = ["std_detect/std_detect_file_io"]
 std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
+std_detect_env_override = ["std_detect/std_detect_env_override"]
 
 [package.metadata.fortanix-sgx]
 # Maximum possible number of threads when testing
index 3978e9b1668e58fa8380b095fb6b81a66ba0e397..f96906be540f99e0abd30348f9835f46f619d10e 100644 (file)
@@ -1258,9 +1258,10 @@ pub(super) fn iter(&self) -> Iter<'_, K, V> {
 /// An owning iterator over the entries of a `HashMap`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`HashMap`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: IntoIterator::into_iter
+/// [`IntoIterator`]: crate::iter::IntoIterator
 ///
 /// # Example
 ///
index 3b61acd122e2e9ddfd91f74626b84ae5a17438d7..941981e3b00f12d55a5450517f5a3197162b67df 100644 (file)
@@ -1237,9 +1237,10 @@ pub struct Iter<'a, K: 'a> {
 /// An owning iterator over the items of a `HashSet`.
 ///
 /// This `struct` is created by the [`into_iter`] method on [`HashSet`]
-/// (provided by the `IntoIterator` trait). See its documentation for more.
+/// (provided by the [`IntoIterator`] trait). See its documentation for more.
 ///
 /// [`into_iter`]: IntoIterator::into_iter
+/// [`IntoIterator`]: crate::iter::IntoIterator
 ///
 /// # Examples
 ///
index 71645aadb1d88b717eb03e341be65ef07a24982b..6ca0525cdbe328de45402ce63fd8c909b19e233b 100644 (file)
 //!
 //! ## Sequences
 //!
-//! |                | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
-//! |----------------|----------------|-----------------|----------------|--------|----------------|
-//! | [`Vec`]        | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
-//! | [`VecDeque`]   | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
-//! | [`LinkedList`] | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
+//! |                | get(i)                 | insert(i)               | remove(i)              | append    | split_off(i)           |
+//! |----------------|------------------------|-------------------------|------------------------|-----------|------------------------|
+//! | [`Vec`]        | *O*(1)                 | *O*(*n*-*i*)*           | *O*(*n*-*i*)           | *O*(*m*)* | *O*(*n*-*i*)           |
+//! | [`VecDeque`]   | *O*(1)                 | *O*(min(*i*, *n*-*i*))* | *O*(min(*i*, *n*-*i*)) | *O*(*m*)* | *O*(min(*i*, *n*-*i*)) |
+//! | [`LinkedList`] | *O*(min(*i*, *n*-*i*)) | *O*(min(*i*, *n*-*i*))  | *O*(min(*i*, *n*-*i*)) | *O*(1)    | *O*(min(*i*, *n*-*i*)) |
 //!
 //! Note that where ties occur, [`Vec`] is generally going to be faster than [`VecDeque`], and
 //! [`VecDeque`] is generally going to be faster than [`LinkedList`].
 //!
 //! For Sets, all operations have the cost of the equivalent Map operation.
 //!
-//! |              | get       | insert    | remove    | range     | append |
-//! |--------------|-----------|-----------|-----------|-----------|--------|
-//! | [`HashMap`]  | O(1)~     | O(1)~*    | O(1)~     | N/A       | N/A    |
-//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) |
+//! |              | get           | insert        | remove        | range         | append       |
+//! |--------------|---------------|---------------|---------------|---------------|--------------|
+//! | [`HashMap`]  | *O*(1)~       | *O*(1)~*      | *O*(1)~       | N/A           | N/A          |
+//! | [`BTreeMap`] | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(*n*+*m*) |
 //!
 //! # Correct and Efficient Usage of Collections
 //!
 //! contents by-value. This is great when the collection itself is no longer
 //! needed, and the values are needed elsewhere. Using `extend` with `into_iter`
 //! is the main way that contents of one collection are moved into another.
-//! `extend` automatically calls `into_iter`, and takes any `T: `[`IntoIterator`].
+//! `extend` automatically calls `into_iter`, and takes any <code>T: [IntoIterator]</code>.
 //! Calling `collect` on an iterator itself is also a great way to convert one
 //! collection into another. Both of these methods should internally use the
 //! capacity management tools discussed in the previous section to do this as
 //! assert_eq!(map.keys().next().unwrap().b, "baz");
 //! ```
 //!
-//! [`IntoIterator`]: crate::iter::IntoIterator
+//! [IntoIterator]: crate::iter::IntoIterator "iter::IntoIterator"
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 8164ec56985791d09c8ed011fda482c1a3484b59..cc4ea27e57e8d36d8c4f0d314bec127dc9540c26 100644 (file)
@@ -31,6 +31,7 @@
 use crate::str;
 use crate::string;
 use crate::sync::Arc;
+use crate::time;
 
 /// `Error` is a trait representing the basic expectations for error values,
 /// i.e., values of type `E` in [`Result<T, E>`].
@@ -598,7 +599,7 @@ fn description(&self) -> &str {
 impl Error for alloc::collections::TryReserveError {}
 
 #[unstable(feature = "duration_checked_float", issue = "83400")]
-impl Error for core::time::FromSecsError {}
+impl Error for time::FromSecsError {}
 
 // Copied from `any.rs`.
 impl dyn Error + 'static {
index 3b9175503080c1e330b2b65a2d67ba420b101a19..ba084987f66e1d532f33767ad2b00d6f112c15a0 100644 (file)
 /// type is a static guarantee that the underlying bytes contain no interior 0
 /// bytes ("nul characters") and that the final byte is 0 ("nul terminator").
 ///
-/// `CString` is to [`&CStr`] as [`String`] is to [`&str`]: the former
+/// `CString` is to <code>&[CStr]</code> as [`String`] is to <code>&[str]</code>: the former
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
 /// # Creating a `CString`
 ///
 /// A `CString` is created from either a byte slice or a byte vector,
-/// or anything that implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>` (for
+/// or anything that implements <code>[Into]<[Vec]<[u8]>></code> (for
 /// example, you can build a `CString` straight out of a [`String`] or
-/// a [`&str`], since both implement that trait).
+/// a <code>&[str]</code>, since both implement that trait).
 ///
-/// The [`CString::new`] method will actually check that the provided `&[u8]`
+/// The [`CString::new`] method will actually check that the provided <code>&[[u8]]</code>
 /// does not have 0 bytes in the middle, and return an error if it
 /// finds one.
 ///
@@ -55,7 +55,7 @@
 ///
 /// # Extracting a slice of the whole C string
 ///
-/// Alternatively, you can obtain a `&[`[`u8`]`]` slice from a
+/// Alternatively, you can obtain a <code>&[[u8]]</code> slice from a
 /// `CString` with the [`CString::as_bytes`] method. Slices produced in this
 /// way do *not* contain the trailing nul terminator. This is useful
 /// when you will be calling an extern function that takes a `*const
@@ -64,7 +64,7 @@
 /// You can of course get the slice's length with its
 /// [`len`][slice::len] method.
 ///
-/// If you need a `&[`[`u8`]`]` slice *with* the nul terminator, you
+/// If you need a <code>&[[u8]]</code> slice *with* the nul terminator, you
 /// can use [`CString::as_bytes_with_nul`] instead.
 ///
 /// Once you have the kind of slice you need (with or without a nul
@@ -73,9 +73,8 @@
 /// extern functions. See the documentation for that function for a
 /// discussion on ensuring the lifetime of the raw pointer.
 ///
-/// [`&str`]: prim@str
+/// [str]: prim@str "str"
 /// [`Deref`]: ops::Deref
-/// [`&CStr`]: CStr
 ///
 /// # Examples
 ///
@@ -120,12 +119,12 @@ pub struct CString {
 /// Representation of a borrowed C string.
 ///
 /// This type represents a borrowed reference to a nul-terminated
-/// array of bytes. It can be constructed safely from a `&[`[`u8`]`]`
+/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code>
 /// slice, or unsafely from a raw `*const c_char`. It can then be
-/// converted to a Rust [`&str`] by performing UTF-8 validation, or
+/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or
 /// into an owned [`CString`].
 ///
-/// `&CStr` is to [`CString`] as [`&str`] is to [`String`]: the former
+/// `&CStr` is to [`CString`] as <code>&[str]</code> is to [`String`]: the former
 /// in each pair are borrowed references; the latter are owned
 /// strings.
 ///
@@ -183,7 +182,7 @@ pub struct CString {
 /// println!("string: {}", my_string_safe());
 /// ```
 ///
-/// [`&str`]: prim@str
+/// [str]: prim@str "str"
 #[derive(Hash)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "CStr")]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -682,7 +681,7 @@ fn into_inner(self) -> Box<[u8]> {
         unsafe { ptr::read(&this.inner) }
     }
 
-    /// Converts a [`Vec`]`<u8>` to a [`CString`] without checking the
+    /// Converts a <code>[Vec]<[u8]></code> to a [`CString`] without checking the
     /// invariants on the given [`Vec`].
     ///
     /// # Safety
@@ -705,7 +704,7 @@ pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
         Self { inner: v.into_boxed_slice() }
     }
 
-    /// Attempts to converts a [`Vec`]`<u8>` to a [`CString`].
+    /// Attempts to converts a <code>[Vec]<[u8]></code> to a [`CString`].
     ///
     /// Runtime checks are present to ensure there is only one nul byte in the
     /// [`Vec`], its last element.
@@ -793,7 +792,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 #[stable(feature = "cstring_into", since = "1.7.0")]
 impl From<CString> for Vec<u8> {
-    /// Converts a [`CString`] into a [`Vec`]`<u8>`.
+    /// Converts a [`CString`] into a <code>[Vec]<[u8]></code>.
     ///
     /// The conversion consumes the [`CString`], and removes the terminating NUL byte.
     #[inline]
@@ -867,7 +866,7 @@ fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
 
 #[stable(feature = "c_string_from_box", since = "1.18.0")]
 impl From<Box<CStr>> for CString {
-    /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
+    /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
     #[inline]
     fn from(s: Box<CStr>) -> CString {
         s.into_c_string()
@@ -876,7 +875,7 @@ fn from(s: Box<CStr>) -> CString {
 
 #[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")]
 impl From<Vec<NonZeroU8>> for CString {
-    /// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without
+    /// Converts a <code>[Vec]<[NonZeroU8]></code> into a [`CString`] without
     /// copying nor checking for inner null bytes.
     #[inline]
     fn from(v: Vec<NonZeroU8>) -> CString {
@@ -906,7 +905,7 @@ fn clone(&self) -> Self {
 
 #[stable(feature = "box_from_c_string", since = "1.20.0")]
 impl From<CString> for Box<CStr> {
-    /// Converts a [`CString`] into a [`Box`]`<CStr>` without copying or allocating.
+    /// Converts a [`CString`] into a <code>[Box]<[CStr]></code> without copying or allocating.
     #[inline]
     fn from(s: CString) -> Box<CStr> {
         s.into_boxed_c_str()
@@ -942,7 +941,7 @@ fn from(s: &'a CString) -> Cow<'a, CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Arc<CStr> {
-    /// Converts a [`CString`] into an [`Arc`]`<CStr>` without copying or allocating.
+    /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> without copying or allocating.
     #[inline]
     fn from(s: CString) -> Arc<CStr> {
         let arc: Arc<[u8]> = Arc::from(s.into_inner());
@@ -961,7 +960,7 @@ fn from(s: &CStr) -> Arc<CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Rc<CStr> {
-    /// Converts a [`CString`] into an [`Rc`]`<CStr>` without copying or allocating.
+    /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> without copying or allocating.
     #[inline]
     fn from(s: CString) -> Rc<CStr> {
         let rc: Rc<[u8]> = Rc::from(s.into_inner());
@@ -1355,13 +1354,13 @@ pub fn to_bytes_with_nul(&self) -> &[u8] {
         unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
     }
 
-    /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
+    /// Yields a <code>&[str]</code> slice if the `CStr` contains valid UTF-8.
     ///
     /// If the contents of the `CStr` are valid UTF-8 data, this
-    /// function will return the corresponding [`&str`] slice. Otherwise,
+    /// function will return the corresponding <code>&[str]</code> slice. Otherwise,
     /// it will return an error with details of where UTF-8 validation failed.
     ///
-    /// [`&str`]: prim@str
+    /// [str]: prim@str "str"
     ///
     /// # Examples
     ///
@@ -1380,20 +1379,19 @@ pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
         str::from_utf8(self.to_bytes())
     }
 
-    /// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`.
+    /// Converts a `CStr` into a <code>[Cow]<[str]></code>.
     ///
     /// If the contents of the `CStr` are valid UTF-8 data, this
-    /// function will return a [`Cow`]`::`[`Borrowed`]`(`[`&str`]`)`
-    /// with the corresponding [`&str`] slice. Otherwise, it will
+    /// function will return a <code>[Cow]::[Borrowed]\(&[str])</code>
+    /// with the corresponding <code>&[str]</code> slice. Otherwise, it will
     /// replace any invalid UTF-8 sequences with
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
-    /// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result.
+    /// <code>[Cow]::[Owned]\(&[str])</code> with the result.
     ///
-    /// [`str`]: primitive@str
-    /// [`&str`]: primitive@str
-    /// [`Borrowed`]: Cow::Borrowed
-    /// [`Owned`]: Cow::Owned
-    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
+    /// [str]: prim@str "str"
+    /// [Borrowed]: Cow::Borrowed
+    /// [Owned]: Cow::Owned
+    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER"
     ///
     /// # Examples
     ///
@@ -1426,7 +1424,7 @@ pub fn to_string_lossy(&self) -> Cow<'_, str> {
         String::from_utf8_lossy(self.to_bytes())
     }
 
-    /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
+    /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
     ///
     /// # Examples
     ///
index fe4e3af91ad0a6df1a738570ac6a33561a72bb56..82a76aa73c583fb78ecaea7bb101cca179d71547 100644 (file)
@@ -43,8 +43,8 @@
 //! terminator, so the buffer length is really `len+1` characters.
 //! Rust strings don't have a nul terminator; their length is always
 //! stored and does not need to be calculated. While in Rust
-//! accessing a string's length is a `O(1)` operation (because the
-//! length is stored); in C it is an `O(length)` operation because the
+//! accessing a string's length is an *O*(1) operation (because the
+//! length is stored); in C it is an *O*(*n*) operation because the
 //! length needs to be computed by scanning the string for the nul
 //! terminator.
 //!
 //! string: it is nul-terminated, and has no internal nul characters.
 //! Rust code can create a [`CString`] out of a normal string (provided
 //! that the string doesn't have nul characters in the middle), and
-//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
+//! then use a variety of methods to obtain a raw <code>\*mut [u8]</code> that can
 //! then be passed as an argument to functions which use the C
 //! conventions for strings.
 //!
 //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
-//! is what you would use to wrap a raw `*const `[`u8`] that you got from
+//! is what you would use to wrap a raw <code>\*const [u8]</code> that you got from
 //! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
 //! of bytes. Once you have a [`CStr`], you can convert it to a Rust
-//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
+//! <code>&[str]</code> if it's valid UTF-8, or lossily convert it by adding
 //! replacement characters.
 //!
 //! [`OsString`] and [`OsStr`] are useful when you need to transfer
@@ -86,9 +86,9 @@
 //! library, various APIs that transfer strings to/from the operating
 //! system use [`OsString`] instead of plain strings. For example,
 //! [`env::var_os()`] is used to query environment variables; it
-//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
-//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
-//! convert to a Rust string. This yields a [`Result`], so that
+//! returns an <code>[Option]<[OsString]></code>. If the environment variable
+//! exists you will get a <code>[Some]\(os_string)</code>, which you can
+//! *then* try to convert to a Rust string. This yields a [`Result`], so that
 //! your code can detect errors in case the environment variable did
 //! not in fact contain valid Unicode data.
 //!
 //! ## On Unix
 //!
 //! On Unix, [`OsStr`] implements the
-//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
+//! <code>std::os::unix::ffi::[OsStrExt][unix.OsStrExt]</code> trait, which
 //! augments it with two methods, [`from_bytes`] and [`as_bytes`].
 //! These do inexpensive conversions from and to UTF-8 byte slices.
 //!
 //! Additionally, on Unix [`OsString`] implements the
-//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
+//! <code>std::os::unix::ffi::[OsStringExt][unix.OsStringExt]</code> trait,
 //! which provides [`from_vec`] and [`into_vec`] methods that consume
 //! their arguments, and take or produce vectors of [`u8`].
 //!
 //! ## On Windows
 //!
 //! On Windows, [`OsStr`] implements the
-//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
+//! <code>std::os::windows::ffi::[OsStrExt][windows.OsStrExt]</code> trait,
 //! which provides an [`encode_wide`] method. This provides an
 //! iterator that can be [`collect`]ed into a vector of [`u16`].
 //!
 //! Additionally, on Windows [`OsString`] implements the
-//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
+//! <code>std::os::windows:ffi::[OsStringExt][windows.OsStringExt]</code>
 //! trait, which provides a [`from_wide`] method. The result of this
 //! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
 //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
 //! [Unicode code point]: https://www.unicode.org/glossary/#code_point
-//! [`env::set_var()`]: crate::env::set_var
-//! [`env::var_os()`]: crate::env::var_os
-//! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt
-//! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec
-//! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec
-//! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt
-//! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes
-//! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes
-//! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt
-//! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt
-//! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide
-//! [`collect`]: crate::iter::Iterator::collect
-//! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt
-//! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide
+//! [`env::set_var()`]: crate::env::set_var "env::set_var"
+//! [`env::var_os()`]: crate::env::var_os "env::var_os"
+//! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt "os::unix::ffi::OsStringExt"
+//! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec "os::unix::ffi::OsStringExt::from_vec"
+//! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec "os::unix::ffi::OsStringExt::into_vec"
+//! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt "os::unix::ffi::OsStrExt"
+//! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes "os::unix::ffi::OsStrExt::from_bytes"
+//! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes "os::unix::ffi::OsStrExt::as_bytes"
+//! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt "os::unix::ffi::OsStrExt"
+//! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt "os::windows::ffi::OsStrExt"
+//! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide "os::windows::ffi::OsStrExt::encode_wide"
+//! [`collect`]: crate::iter::Iterator::collect "iter::Iterator::collect"
+//! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt "os::windows::ffi::OsStringExt"
+//! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide "os::windows::ffi::OsStringExt::from_wide"
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 21f354caf6ae9fba2d1ed486ff7411a5dec7e9ea..7e70901076cdadc96c8855cda6958f786989f9ef 100644 (file)
@@ -33,7 +33,7 @@
 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
 /// to pass to e.g., Unix system call, you should create a [`CStr`].
 ///
-/// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
+/// `OsString` is to <code>&[OsStr]</code> as [`String`] is to <code>&[str]</code>: the former
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
 /// # Creating an `OsString`
 ///
 /// **From a Rust string**: `OsString` implements
-/// [`From`]`<`[`String`]`>`, so you can use `my_string.from` to
+/// <code>[From]<[String]></code>, so you can use <code>my_string.[into]\()</code> to
 /// create an `OsString` from a normal Rust string.
 ///
 /// **From slices:** Just like you can start with an empty Rust
-/// [`String`] and then [`String::push_str`] `&str`
+/// [`String`] and then [`String::push_str`] some <code>&[str]</code>
 /// sub-string slices into it, you can create an empty `OsString` with
 /// the [`OsString::new`] method and then push string slices into it with the
 /// [`OsString::push`] method.
 ///
 /// # Extracting a borrowed reference to the whole OS string
 ///
-/// You can use the [`OsString::as_os_str`] method to get an `&`[`OsStr`] from
+/// You can use the [`OsString::as_os_str`] method to get an <code>&[OsStr]</code> from
 /// an `OsString`; this is effectively a borrowed reference to the
 /// whole string.
 ///
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsString` implements for [conversions] from/to native representations.
 ///
-/// [`&OsStr`]: OsStr
-/// [`&str`]: str
 /// [`CStr`]: crate::ffi::CStr
 /// [conversions]: super#conversions
+/// [into]: Into::into
 #[cfg_attr(not(test), rustc_diagnostic_item = "OsString")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsString {
@@ -86,13 +85,12 @@ impl crate::sealed::Sealed for OsString {}
 /// This type represents a borrowed reference to a string in the operating system's preferred
 /// representation.
 ///
-/// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
-/// references; the latter are owned strings.
+/// `&OsStr` is to [`OsString`] as <code>&[str]</code> is to [`String`]: the
+/// former in each pair are borrowed references; the latter are owned strings.
 ///
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsStr` implements for [conversions] from/to native representations.
 ///
-/// [`&str`]: str
 /// [conversions]: super#conversions
 #[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -162,9 +160,7 @@ pub fn into_string(self) -> Result<String, OsString> {
         self.inner.into_string().map_err(|buf| OsString { inner: buf })
     }
 
-    /// Extends the string with the given [`&OsStr`] slice.
-    ///
-    /// [`&OsStr`]: OsStr
+    /// Extends the string with the given <code>&[OsStr]</code> slice.
     ///
     /// # Examples
     ///
@@ -563,12 +559,10 @@ fn from_inner_mut(inner: &mut Slice) -> &mut OsStr {
         unsafe { &mut *(inner as *mut Slice as *mut OsStr) }
     }
 
-    /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
+    /// Yields a <code>&[str]</code> slice if the `OsStr` is valid Unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
     ///
-    /// [`&str`]: str
-    ///
     /// # Examples
     ///
     /// ```
@@ -583,7 +577,7 @@ pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
     }
 
-    /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
+    /// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
     ///
     /// Any non-Unicode sequences are replaced with
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
@@ -701,7 +695,7 @@ pub fn len(&self) -> usize {
         self.inner.inner.len()
     }
 
-    /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
+    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or allocating.
     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
     pub fn into_os_string(self: Box<OsStr>) -> OsString {
         let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
@@ -870,7 +864,7 @@ fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
 
 #[stable(feature = "os_string_from_box", since = "1.18.0")]
 impl From<Box<OsStr>> for OsString {
-    /// Converts a [`Box`]`<`[`OsStr`]`>` into an [`OsString`] without copying or
+    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or
     /// allocating.
     #[inline]
     fn from(boxed: Box<OsStr>) -> OsString {
@@ -880,7 +874,7 @@ fn from(boxed: Box<OsStr>) -> OsString {
 
 #[stable(feature = "box_from_os_string", since = "1.20.0")]
 impl From<OsString> for Box<OsStr> {
-    /// Converts an [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
+    /// Converts an [`OsString`] into a <code>[Box]<[OsStr]></code> without copying or allocating.
     #[inline]
     fn from(s: OsString) -> Box<OsStr> {
         s.into_boxed_os_str()
@@ -897,7 +891,7 @@ fn clone(&self) -> Self {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Arc<OsStr> {
-    /// Converts an [`OsString`] into an [`Arc`]`<OsStr>` without copying or allocating.
+    /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> without copying or allocating.
     #[inline]
     fn from(s: OsString) -> Arc<OsStr> {
         let arc = s.inner.into_arc();
@@ -916,7 +910,7 @@ fn from(s: &OsStr) -> Arc<OsStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Rc<OsStr> {
-    /// Converts an [`OsString`] into an [`Rc`]`<OsStr>` without copying or allocating.
+    /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> without copying or allocating.
     #[inline]
     fn from(s: OsString) -> Rc<OsStr> {
         let rc = s.inner.into_rc();
index bdb172907ffed39b770d802093c2ea416d485365..e4b44c0489807bca10e7b279d395925c37b7ad3f 100644 (file)
@@ -106,7 +106,7 @@ pub struct File {
 /// Iterator over the entries in a directory.
 ///
 /// This iterator is returned from the [`read_dir`] function of this module and
-/// will yield instances of [`io::Result`]`<`[`DirEntry`]`>`. Through a [`DirEntry`]
+/// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]
 /// information like the entry's path and possibly other metadata can be
 /// learned.
 ///
@@ -786,17 +786,17 @@ pub fn write(&mut self, write: bool) -> &mut Self {
     /// If a file is opened with both read and append access, beware that after
     /// opening, and after every write, the position for reading may be set at the
     /// end of the file. So, before writing, save the current position (using
-    /// [`seek`]`(`[`SeekFrom`]`::`[`Current`]`(0))`), and restore it before the next read.
+    /// <code>[seek]\([SeekFrom]::[Current]\(0))</code>), and restore it before the next read.
     ///
     /// ## Note
     ///
     /// This function doesn't create the file if it doesn't exist. Use the
     /// [`OpenOptions::create`] method to do so.
     ///
-    /// [`write()`]: Write::write
-    /// [`flush()`]: Write::flush
-    /// [`seek`]: Seek::seek
-    /// [`Current`]: SeekFrom::Current
+    /// [`write()`]: Write::write "io::Write::write"
+    /// [`flush()`]: Write::flush "io::Write::flush"
+    /// [seek]: Seek::seek "io::Seek::seek"
+    /// [Current]: SeekFrom::Current "io::SeekFrom::Current"
     ///
     /// # Examples
     ///
@@ -2043,7 +2043,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 
 /// Returns an iterator over the entries within a directory.
 ///
-/// The iterator will yield instances of [`io::Result`]`<`[`DirEntry`]`>`.
+/// The iterator will yield instances of <code>[io::Result]<[DirEntry]></code>.
 /// New errors may be encountered after an iterator is initially constructed.
 /// Entries for the current and parent directories (typically `.` and `..`) are
 /// skipped.
index 32d194d9616523c6ae46a426acf602139ade7fbe..869ac1ec8596c1324b915b9479a46f7649e9b9b5 100644 (file)
@@ -15,7 +15,7 @@
 /// *repeated* read calls to the same file or network socket. It does not
 /// help when reading very large amounts at once, or reading just one or a few
 /// times. It also provides no advantage when reading from a source that is
-/// already in memory, like a [`Vec`]`<u8>`.
+/// already in memory, like a <code>[Vec]\<u8></code>.
 ///
 /// When the `BufReader<R>` is dropped, the contents of its buffer will be
 /// discarded. Creating multiple instances of a `BufReader<R>` on the same
@@ -347,7 +347,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 impl<R: Seek> Seek for BufReader<R> {
     /// Seek to an offset, in bytes, in the underlying reader.
     ///
-    /// The position used for seeking with [`SeekFrom::Current`]`(_)` is the
+    /// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
     /// position the underlying reader would be at if the `BufReader<R>` had no
     /// internal buffer.
     ///
@@ -360,11 +360,11 @@ impl<R: Seek> Seek for BufReader<R> {
     ///
     /// See [`std::io::Seek`] for more details.
     ///
-    /// Note: In the edge case where you're seeking with [`SeekFrom::Current`]`(n)`
+    /// Note: In the edge case where you're seeking with <code>[SeekFrom::Current]\(n)</code>
     /// where `n` minus the internal buffer length overflows an `i64`, two
     /// seeks will be performed instead of one. If the second seek returns
     /// [`Err`], the underlying reader will be left at the same position it would
-    /// have if you called `seek` with [`SeekFrom::Current`]`(0)`.
+    /// have if you called `seek` with <code>[SeekFrom::Current]\(0)</code>.
     ///
     /// [`std::io::Seek`]: Seek
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
index df60af7c36a3e236a73c6fb8abef22fd217fa989..ebbda7c1bf2a0b6fa8a45e563fa0db4f373bc4d2 100644 (file)
@@ -18,7 +18,7 @@
 /// *repeated* write calls to the same file or network socket. It does not
 /// help when writing very large amounts at once, or writing just one or a few
 /// times. It also provides no advantage when writing to a destination that is
-/// in memory, like a [`Vec`]`<u8>`.
+/// in memory, like a <code>[Vec]\<u8></code>.
 ///
 /// It is critical to call [`flush`] before `BufWriter<W>` is dropped. Though
 /// dropping will attempt to flush the contents of the buffer, any errors
index ae0cea985d77c9b8314044d7eaad75e2e07581a1..25cc5e67ad14e37ddfd6ed337edadef5f39dd006 100644 (file)
 /// [`Seek`] implementation.
 ///
 /// `Cursor`s are used with in-memory buffers, anything implementing
-/// [`AsRef`]`<[u8]>`, to allow them to implement [`Read`] and/or [`Write`],
+/// <code>[AsRef]<\[u8]></code>, to allow them to implement [`Read`] and/or [`Write`],
 /// allowing these buffers to be used anywhere you might use a reader or writer
 /// that does actual I/O.
 ///
 /// The standard library implements some I/O traits on various types which
-/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
-/// `Cursor<`[`&[u8]`][bytes]`>`.
+/// are commonly used as a buffer, like <code>Cursor<[Vec]\<u8>></code> and
+/// <code>Cursor<[&\[u8\]][bytes]></code>.
 ///
 /// # Examples
 ///
@@ -26,7 +26,7 @@
 /// code, but use an in-memory buffer in our tests. We can do this with
 /// `Cursor`:
 ///
-/// [bytes]: crate::slice
+/// [bytes]: crate::slice "slice"
 /// [`File`]: crate::fs::File
 ///
 /// ```no_run
index 4a35d36a9def72f284b48244219b347a9d140e80..f8ebbe1cba721736cf555e684ee81aef547b83ea 100644 (file)
@@ -854,8 +854,8 @@ fn by_ref(&mut self) -> &mut Self
 
     /// Transforms this `Read` instance to an [`Iterator`] over its bytes.
     ///
-    /// The returned type implements [`Iterator`] where the `Item` is
-    /// [`Result`]`<`[`u8`]`, `[`io::Error`]`>`.
+    /// The returned type implements [`Iterator`] where the [`Item`] is
+    /// <code>[Result]<[u8], [io::Error]></code>.
     /// The yielded item is [`Ok`] if a byte was successfully read and [`Err`]
     /// otherwise. EOF is mapped to returning [`None`] from this iterator.
     ///
@@ -863,9 +863,10 @@ fn by_ref(&mut self) -> &mut Self
     ///
     /// [`File`]s implement `Read`:
     ///
-    /// [`File`]: crate::fs::File
-    /// [`Result`]: crate::result::Result
-    /// [`io::Error`]: self::Error
+    /// [`Item`]: Iterator::Item
+    /// [`File`]: crate::fs::File "fs::File"
+    /// [Result]: crate::result::Result "Result"
+    /// [io::Error]: self::Error "io::Error"
     ///
     /// ```no_run
     /// use std::io;
@@ -2191,13 +2192,13 @@ fn read_line(&mut self, buf: &mut String) -> Result<usize> {
     /// `byte`.
     ///
     /// The iterator returned from this function will return instances of
-    /// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
+    /// <code>[io::Result]<[Vec]\<u8>></code>. Each vector returned will *not* have
     /// the delimiter byte at the end.
     ///
     /// This function will yield errors whenever [`read_until`] would have
     /// also yielded an error.
     ///
-    /// [`io::Result`]: self::Result
+    /// [io::Result]: self::Result "io::Result"
     /// [`read_until`]: BufRead::read_until
     ///
     /// # Examples
@@ -2228,10 +2229,10 @@ fn split(self, byte: u8) -> Split<Self>
     /// Returns an iterator over the lines of this reader.
     ///
     /// The iterator returned from this function will yield instances of
-    /// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline
+    /// <code>[io::Result]<[String]></code>. Each string returned will *not* have a newline
     /// byte (the `0xA` byte) or `CRLF` (`0xD`, `0xA` bytes) at the end.
     ///
-    /// [`io::Result`]: self::Result
+    /// [io::Result]: self::Result "io::Result"
     ///
     /// # Examples
     ///
index a8812f197d82d3c269dc001d2eb98a5f450a74a1..2f3520ae7a5a5fb4c9aab4c4364b64fe334b5d70 100644 (file)
@@ -19,7 +19,7 @@
 
 /// Constructs a new handle to an empty reader.
 ///
-/// All reads from the returned reader will return [`Ok`]`(0)`.
+/// All reads from the returned reader will return <code>[Ok]\(0)</code>.
 ///
 /// # Examples
 ///
index 43d930677fad3d53e41712f6844bf9b19d54f49c..f4ebcd53a25f7482c3f6736de8d045828c8193b8 100644 (file)
@@ -765,15 +765,15 @@ fn hash<H: hash::Hasher>(&self, s: &mut H) {
 ///
 ///  * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
 ///
-///  * [`SocketAddrV4`], [`SocketAddrV6`], `(`[`IpAddr`]`, `[`u16`]`)`,
-///    `(`[`Ipv4Addr`]`, `[`u16`]`)`, `(`[`Ipv6Addr`]`, `[`u16`]`)`:
+///  * [`SocketAddrV4`], [`SocketAddrV6`], <code>([IpAddr], [u16])</code>,
+///    <code>([Ipv4Addr], [u16])</code>, <code>([Ipv6Addr], [u16])</code>:
 ///    [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
 ///
-///  * `(`[`&str`]`, `[`u16`]`)`: [`&str`] should be either a string representation
+///  * <code>(&[str], [u16])</code>: <code>&[str]</code> should be either a string representation
 ///    of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
 ///    name. [`u16`] is the port number.
 ///
-///  * [`&str`]: the string should be either a string representation of a
+///  * <code>&[str]</code>: the string should be either a string representation of a
 ///    [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
 ///    `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
 ///
@@ -789,11 +789,10 @@ fn hash<H: hash::Hasher>(&self, s: &mut H) {
 /// Addresses returned by the operating system that are not IP addresses are
 /// silently ignored.
 ///
-/// [`FromStr`]: crate::str::FromStr
-/// [`&str`]: str
-/// [`TcpStream`]: crate::net::TcpStream
+/// [`FromStr`]: crate::str::FromStr "std::str::FromStr"
+/// [`TcpStream`]: crate::net::TcpStream "net::TcpStream"
 /// [`to_socket_addrs`]: ToSocketAddrs::to_socket_addrs
-/// [`UdpSocket`]: crate::net::UdpSocket
+/// [`UdpSocket`]: crate::net::UdpSocket "net::UdpSocket"
 ///
 /// # Examples
 ///
@@ -872,7 +871,7 @@ pub trait ToSocketAddrs {
     #[stable(feature = "rust1", since = "1.0.0")]
     type Iter: Iterator<Item = SocketAddr>;
 
-    /// Converts this object to an iterator of resolved `SocketAddr`s.
+    /// Converts this object to an iterator of resolved [`SocketAddr`]s.
     ///
     /// The returned iterator might not actually yield any values depending on the
     /// outcome of any resolution performed.
index d814e9b25ba9a0be62e0a6432289883da51d565d..a0c77b648fe0511a8c56cabbf14e3a09707a9977 100644 (file)
 pub enum Shutdown {
     /// The reading portion of the [`TcpStream`] should be shut down.
     ///
-    /// All currently blocked and future [reads] will return [`Ok`]`(0)`.
+    /// All currently blocked and future [reads] will return <code>[Ok]\(0)</code>.
     ///
-    /// [reads]: crate::io::Read
+    /// [reads]: crate::io::Read "io::Read"
     #[stable(feature = "rust1", since = "1.0.0")]
     Read,
     /// The writing portion of the [`TcpStream`] should be shut down.
     ///
     /// All currently blocked and future [writes] will return an error.
     ///
-    /// [writes]: crate::io::Write
+    /// [writes]: crate::io::Write "io::Write"
     #[stable(feature = "rust1", since = "1.0.0")]
     Write,
     /// Both the reading and the writing portions of the [`TcpStream`] should be shut down.
index 8256b725acfa399877768d57c53b9b6c35915d4b..375d070516eb49bcbf7c1d047b107f6e817275da 100644 (file)
@@ -1,6 +1,6 @@
 Equivalent to C's `char` type.
 
-[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. This type will always be either [`i8`] or [`u8`], as the type is defined as being one byte long.
+[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. On modern architectures this type will always be either [`i8`] or [`u8`], as they use byte-addresses memory with 8-bit bytes.
 
 C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information.
 
index 2a9c361c18afc03ec06972fb8d5af6938d34864e..9d5778ed48cfe5803660f5502b4911d83c1bd70a 100644 (file)
@@ -2552,7 +2552,7 @@ pub fn read_link(&self) -> io::Result<PathBuf> {
 
     /// Returns an iterator over the entries within a directory.
     ///
-    /// The iterator will yield instances of [`io::Result`]`<`[`fs::DirEntry`]`>`. New
+    /// The iterator will yield instances of <code>[io::Result]<[fs::DirEntry]></code>. New
     /// errors may be encountered after an iterator is initially constructed.
     ///
     /// This is an alias to [`fs::read_dir`].
index 0c32e636a563357ce39cac0f6313c422b4915c1c..8487a5f8b50d3215790285d4841ac2ec1021afc4 100644 (file)
@@ -248,7 +248,11 @@ pub fn recv(&self, deadline: Option<Instant>) -> Result<T, Failure> {
     // Returns true if blocking should proceed.
     fn decrement(&self, token: SignalToken) -> StartResult {
         unsafe {
-            assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
+            assert_eq!(
+                self.to_wake.load(Ordering::SeqCst),
+                0,
+                "This is a known bug in the Rust standard library. See https://github.com/rust-lang/rust/issues/39364"
+            );
             let ptr = token.cast_to_usize();
             self.to_wake.store(ptr, Ordering::SeqCst);
 
index 0c1a50e231cd4f87cbfd63a85a4e1b5be5806237..cc137771bb8d41bf79c4dd6efa7717e330901b1d 100644 (file)
@@ -357,7 +357,7 @@ pub fn file_attr(&self) -> io::Result<FileAttr> {
             let mut info: c::FILE_BASIC_INFO = mem::zeroed();
             let size = mem::size_of_val(&info);
             cvt(c::GetFileInformationByHandleEx(
-                self.handle.raw(),
+                self.handle.as_raw_handle(),
                 c::FileBasicInfo,
                 &mut info as *mut _ as *mut libc::c_void,
                 size as c::DWORD,
@@ -385,7 +385,7 @@ pub fn file_attr(&self) -> io::Result<FileAttr> {
             let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
             let size = mem::size_of_val(&info);
             cvt(c::GetFileInformationByHandleEx(
-                self.handle.raw(),
+                self.handle.as_raw_handle(),
                 c::FileStandardInfo,
                 &mut info as *mut _ as *mut libc::c_void,
                 size as c::DWORD,
index 872511af862a72d47ce767a0975fba1083600617..32550f796ec64d8ba818caf51d00c18100e3041a 100644 (file)
@@ -2,6 +2,7 @@
 
 use crate::io;
 use crate::mem::ManuallyDrop;
+use crate::os::windows::io::FromRawHandle;
 use crate::sys::c;
 use crate::sys::handle::Handle;
 
@@ -25,7 +26,8 @@ pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
 
 fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> {
     let handle = get_handle(handle_id)?;
-    let handle = Handle::new(handle);
+    // SAFETY: The handle returned from `get_handle` must be valid and non-null.
+    let handle = unsafe { Handle::from_raw_handle(handle) };
     ManuallyDrop::new(handle).write(data)
 }
 
@@ -38,7 +40,8 @@ pub const fn new() -> Stdin {
 impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         let handle = get_handle(c::STD_INPUT_HANDLE)?;
-        let handle = Handle::new(handle);
+        // SAFETY: The handle returned from `get_handle` must be valid and non-null.
+        let handle = unsafe { Handle::from_raw_handle(handle) };
         ManuallyDrop::new(handle).read(buf)
     }
 }
index e9207ee36171b18d44613c17583cf0a77f0232e0..a4f7409b3594a5256a6831cbbeeaa52c8b754531 100644 (file)
@@ -44,6 +44,9 @@
 #[stable(feature = "time", since = "1.3.0")]
 pub use core::time::Duration;
 
+#[unstable(feature = "duration_checked_float", issue = "83400")]
+pub use core::time::FromSecsError;
+
 /// A measurement of a monotonically nondecreasing clock.
 /// Opaque and useful only with [`Duration`].
 ///
@@ -469,7 +472,7 @@ pub fn now() -> SystemTime {
     /// as the system clock being adjusted either forwards or backwards).
     /// [`Instant`] can be used to measure elapsed time without this risk of failure.
     ///
-    /// If successful, [`Ok`]`(`[`Duration`]`)` is returned where the duration represents
+    /// If successful, <code>[Ok]\([Duration])</code> is returned where the duration represents
     /// the amount of time elapsed from the specified measurement to this one.
     ///
     /// Returns an [`Err`] if `earlier` is later than `self`, and the error
@@ -496,7 +499,7 @@ pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTime
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
-    /// function might not always succeed. If successful, [`Ok`]`(`[`Duration`]`)` is
+    /// function might not always succeed. If successful, <code>[Ok]\([Duration])</code> is
     /// returned where the duration represents the amount of time elapsed from
     /// this time measurement to the current time.
     ///
index 80d6072e9b5c23376a26a823807cc76f2686b216..04dab6b804acc2e5f2b35556995ad1a318407cf7 100644 (file)
@@ -33,3 +33,4 @@ panic_immediate_abort = ["std/panic_immediate_abort"]
 profiler = ["std/profiler"]
 std_detect_file_io = ["std/std_detect_file_io"]
 std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
+std_detect_env_override = ["std/std_detect_env_override"]
index 0b76a13e02b7774334b87bf1dd83a3f5728f381c..1ce1f0b26db58030254cf0a903fa10d751476da3 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "bootstrap"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 build = "build.rs"
 
 [lib]
index f5fad4b4136849c8f023eda32bb9d71365f7e1b1..f66f282bea933e0bfbf817f589e74c814eb3fd16 100644 (file)
@@ -262,7 +262,7 @@ fn run(self, builder: &Builder<'_>) {
         let mut cargo = builder.cargo(
             compiler,
             Mode::Codegen,
-            SourceType::Submodule,
+            SourceType::InTree,
             target,
             cargo_subcommand(builder.kind),
         );
index df9e9bce415276245571bf083e0608ee390e1d88..ae234fb1dc729ba9cef9b98992c44dbd88252b99 100644 (file)
@@ -817,8 +817,7 @@ fn run(self, builder: &Builder<'_>) {
 
         let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
 
-        let mut cargo =
-            builder.cargo(compiler, Mode::Codegen, SourceType::Submodule, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, SourceType::InTree, target, "build");
         cargo
             .arg("--manifest-path")
             .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
index af3774b7c7586ef3f33d38747405153b0eb4dff0..14e3b315924188be79cd3b72350b4789c7f9744f 100644 (file)
@@ -743,6 +743,7 @@ fn run(self, builder: &Builder<'_>) {
                 cargo.rustdocflag("--document-private-items");
                 cargo.rustdocflag("--enable-index-page");
                 cargo.rustdocflag("--show-type-layout");
+                cargo.rustdocflag("--generate-link-to-definition");
                 cargo.rustdocflag("-Zunstable-options");
                 builder.run(&mut cargo.into());
             }
index a4735d54be03828f1d91c37a3c507c85f4cefc00..2d4e15278972469bacd9de44c1b11b34fcaf39f5 100644 (file)
@@ -1494,8 +1494,13 @@ fn ninja(&self) -> bool {
             {
                 eprintln!(
                     "
-Couldn't find required command: ninja
-You should install ninja, or set `ninja=false` in config.toml in the `[llvm]` section.
+Couldn't find required command: ninja (or ninja-build)
+
+You should install ninja as described at
+<https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages>,
+or set `ninja = false` in the `[llvm]` section of `config.toml`.
+Alternatively, set `download-ci-llvm = true` in that `[llvm]` section
+to download LLVM rather than building it.
 "
                 );
                 std::process::exit(1);
index 386ffb384a81ee744d9201e516ce466800c92a61..272b7153111370a1a341474b84f971857fc096e4 100644 (file)
@@ -390,7 +390,7 @@ fn run(self, builder: &Builder<'_>) {
             host,
             "test",
             "src/tools/rustfmt",
-            SourceType::Submodule,
+            SourceType::InTree,
             &[],
         );
 
index 17a9e55b3238cd0345b00012b3c1c3bbe1fede82..d88df0e08fab3e01ef9b596bcf58629a01710301 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "build_helper"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 path = "lib.rs"
index b55db452f124c52708d94cdbafb1789d538aa80f..917959976411cf700b4781bfb6d7cc73ed61fb75 100644 (file)
@@ -209,6 +209,22 @@ some consideration for their stability, and names that end in a number). Giving
 `rustdoc` will disable this sorting and instead make it print the items in the order they appear in
 the source.
 
+### `--show-type-layout`: add a section to each type's docs describing its memory layout
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --show-type-layout
+```
+
+When this flag is passed, rustdoc will add a "Layout" section at the bottom of
+each type's docs page that includes a summary of the type's memory layout as
+computed by rustc. For example, rustdoc will show the size in bytes that a value
+of that type will take in memory.
+
+Note that most layout information is **completely unstable** and may even differ
+between compilations.
+
 ### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs
 
 Using this flag looks like this:
@@ -333,7 +349,7 @@ Some methodology notes about what rustdoc counts in this metric:
 Public items that are not documented can be seen with the built-in `missing_docs` lint. Private
 items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint.
 
-## `-w`/`--output-format`: output format
+### `-w`/`--output-format`: output format
 
 When using
 [`--show-coverage`](https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#--show-coverage-get-statistics-about-code-documentation-coverage),
diff --git a/src/doc/unstable-book/src/language-features/closure-track-caller.md b/src/doc/unstable-book/src/language-features/closure-track-caller.md
new file mode 100644 (file)
index 0000000..c948810
--- /dev/null
@@ -0,0 +1,12 @@
+# `closure_track_caller`
+
+The tracking issue for this feature is: [#87417]
+
+[#87417]: https://github.com/rust-lang/rust/issues/87417
+
+------------------------
+
+Allows using the `#[track_caller]` attribute on closures and generators.
+Calls made to the closure or generator will have caller information
+available through `std::panic::Location::caller()`, just like using
+`#[track_caller]` on a function.
index 8226e815c2c1e846f4dec07d07943076abc4e8e1..7ee19a0b6d91397540034fd1bea8a614435cacd6 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "test-float-parse"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 publish = false
 
 [workspace]
index e02cef235ae00331c5d3aa0ab6b70f6b2df0efb8..945b2a8e9a80e75c8f011041f45f20264ce46a9a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 path = "lib.rs"
index 11adb56490b32406e54f218cfe30b53aad27344f..1436e51f31820b27c11003960e1fae161f9a4bc3 100644 (file)
@@ -114,7 +114,7 @@ fn generate_for_trait(
             attrs: Default::default(),
             visibility: Inherited,
             def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
-            kind: Box::new(ImplItem(Impl {
+            kind: box ImplItem(Impl {
                 span: Span::dummy(),
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
@@ -124,7 +124,7 @@ fn generate_for_trait(
                 negative_polarity,
                 synthetic: true,
                 blanket_impl: None,
-            })),
+            }),
             cfg: None,
         })
     }
@@ -354,7 +354,7 @@ fn make_final_bounds(
                     let (poly_trait, output) =
                         (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new));
                     let new_ty = match poly_trait.trait_ {
-                        Type::ResolvedPath { ref path, ref did, ref is_generic } => {
+                        Type::ResolvedPath { ref path, ref did } => {
                             let mut new_path = path.clone();
                             let last_segment =
                                 new_path.segments.pop().expect("segments were empty");
@@ -389,11 +389,7 @@ fn make_final_bounds(
                                 .segments
                                 .push(PathSegment { name: last_segment.name, args: new_params });
 
-                            Type::ResolvedPath {
-                                path: new_path,
-                                did: *did,
-                                is_generic: *is_generic,
-                            }
+                            Type::ResolvedPath { path: new_path, did: *did }
                         }
                         _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
                     };
@@ -563,11 +559,7 @@ fn param_env_to_generics(
                         Type::QPath { name: left_name, ref self_type, ref trait_, .. } => {
                             let ty = &*self_type;
                             match **trait_ {
-                                Type::ResolvedPath {
-                                    path: ref trait_path,
-                                    ref did,
-                                    ref is_generic,
-                                } => {
+                                Type::ResolvedPath { path: ref trait_path, ref did } => {
                                     let mut new_trait_path = trait_path.clone();
 
                                     if self.is_fn_ty(trait_) && left_name == sym::Output {
@@ -612,7 +604,6 @@ fn param_env_to_generics(
                                             trait_: Type::ResolvedPath {
                                                 path: new_trait_path,
                                                 did: *did,
-                                                is_generic: *is_generic,
                                             },
                                             generic_params: Vec::new(),
                                         },
index 15d4563ad7461b7d083439bb726cd3a8b0289129..8135d4a2085dd4c3f8838b00f302bbfdbc2dc47e 100644 (file)
@@ -64,7 +64,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .instantiate(self.cx.tcx, impl_substs)
                             .predicates
                             .into_iter()
-                            .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
+                            .chain(Some(
+                                ty::Binder::dummy(trait_ref)
+                                    .without_const()
+                                    .to_predicate(infcx.tcx),
+                            ));
                         for predicate in predicates {
                             debug!("testing predicate {:?}", predicate);
                             let obligation = traits::Obligation::new(
@@ -100,7 +104,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     attrs: Default::default(),
                     visibility: Inherited,
                     def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
-                    kind: Box::new(ImplItem(Impl {
+                    kind: box ImplItem(Impl {
                         span: Span::new(self.cx.tcx.def_span(impl_def_id)),
                         unsafety: hir::Unsafety::Normal,
                         generics: (
@@ -121,8 +125,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .clean(self.cx),
                         negative_polarity: false,
                         synthetic: false,
-                        blanket_impl: Some(Box::new(trait_ref.self_ty().clean(self.cx))),
-                    })),
+                        blanket_impl: Some(box trait_ref.self_ty().clean(self.cx)),
+                    }),
                     cfg: None,
                 });
             }
index 29834c82b3de32a20d02e3a54aeec942089ddc50..4a888b22332ee98fa18b915f27de6a52ebe0a3ec 100644 (file)
 
     let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
     cx.inlined.insert(did.into());
-    let mut item = clean::Item::from_def_id_and_attrs_and_parts(
-        did,
-        Some(name),
-        kind,
-        Box::new(attrs),
-        cx,
-        cfg,
-    );
+    let mut item =
+        clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cx, cfg);
     if let Some(import_def_id) = import_def_id {
         // The visibility needs to reflect the one from the reexport and not from the "source" DefId.
         item.visibility = cx.tcx.visibility(import_def_id).clean(cx);
@@ -395,13 +389,45 @@ fn merge_attrs(
         }
     }
 
+    let document_hidden = cx.render_options.document_hidden;
     let predicates = tcx.explicit_predicates_of(did);
     let (trait_items, generics) = match impl_item {
         Some(impl_) => (
             impl_
                 .items
                 .iter()
-                .map(|item| tcx.hir().impl_item(item.id).clean(cx))
+                .map(|item| tcx.hir().impl_item(item.id))
+                .filter(|item| {
+                    // Filter out impl items whose corresponding trait item has `doc(hidden)`
+                    // not to document such impl items.
+                    // For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
+
+                    // When `--document-hidden-items` is passed, we don't
+                    // do any filtering, too.
+                    if document_hidden {
+                        return true;
+                    }
+                    if let Some(associated_trait) = associated_trait {
+                        let assoc_kind = match item.kind {
+                            hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
+                            hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
+                            hir::ImplItemKind::TyAlias(..) => ty::AssocKind::Type,
+                        };
+                        let trait_item = tcx
+                            .associated_items(associated_trait.def_id)
+                            .find_by_name_and_kind(
+                                tcx,
+                                item.ident,
+                                assoc_kind,
+                                associated_trait.def_id,
+                            )
+                            .unwrap(); // SAFETY: For all impl items there exists trait item that has the same name.
+                        !tcx.get_attrs(trait_item.def_id).lists(sym::doc).has_word(sym::hidden)
+                    } else {
+                        true
+                    }
+                })
+                .map(|item| item.clean(cx))
                 .collect::<Vec<_>>(),
             impl_.generics.clean(cx),
         ),
@@ -464,7 +490,7 @@ fn merge_attrs(
             synthetic: false,
             blanket_impl: None,
         }),
-        Box::new(merged_attrs),
+        box merged_attrs,
         cx,
         cfg,
     ));
@@ -493,10 +519,10 @@ fn build_module(
                 let prim_ty = clean::PrimitiveType::from(p);
                 items.push(clean::Item {
                     name: None,
-                    attrs: Box::new(clean::Attributes::default()),
+                    attrs: box clean::Attributes::default(),
                     def_id: ItemId::Primitive(prim_ty, did.krate),
                     visibility: clean::Public,
-                    kind: Box::new(clean::ImportItem(clean::Import::new_simple(
+                    kind: box clean::ImportItem(clean::Import::new_simple(
                         item.ident.name,
                         clean::ImportSource {
                             path: clean::Path {
@@ -513,7 +539,7 @@ fn build_module(
                             did: None,
                         },
                         true,
-                    ))),
+                    )),
                     cfg: None,
                 });
             } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
index e281bbc59c255c26e0b707e225d6356e5e60e6df..611a4d08ab2255ee6612a4e81ab583bfd034748d 100644 (file)
@@ -132,7 +132,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
             hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
                 let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
 
-                let trait_ref = ty::TraitRef::identity(cx.tcx, def_id);
+                let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();
 
                 let generic_args = generic_args.clean(cx);
                 let bindings = match generic_args {
@@ -168,7 +168,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
-        ResolvedPath { path, did: trait_ref.def_id, is_generic: false }
+        ResolvedPath { path, did: trait_ref.def_id }
     }
 }
 
@@ -392,8 +392,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         Type::QPath {
             name: cx.tcx.associated_item(self.item_def_id).ident.name,
             self_def_id: self_type.def_id(),
-            self_type: Box::new(self_type),
-            trait_: Box::new(trait_),
+            self_type: box self_type,
+            trait_: box trait_,
         }
     }
 }
@@ -1284,8 +1284,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
             Type::QPath {
                 name: p.segments.last().expect("segments were empty").ident.name,
                 self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
-                self_type: Box::new(qself.clean(cx)),
-                trait_: Box::new(resolve_type(cx, trait_path)),
+                self_type: box qself.clean(cx),
+                trait_: box resolve_type(cx, trait_path),
             }
         }
         hir::QPath::TypeRelative(ref qself, ref segment) => {
@@ -1300,8 +1300,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
             Type::QPath {
                 name: segment.ident.name,
                 self_def_id: res.opt_def_id(),
-                self_type: Box::new(qself.clean(cx)),
-                trait_: Box::new(resolve_type(cx, trait_path)),
+                self_type: box qself.clean(cx),
+                trait_: box resolve_type(cx, trait_path),
             }
         }
         hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
@@ -1314,7 +1314,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
 
         match self.kind {
             TyKind::Never => Never,
-            TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(m.ty.clean(cx))),
+            TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
             TyKind::Rptr(ref l, ref m) => {
                 // There are two times a `Fresh` lifetime can be created:
                 // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
@@ -1326,9 +1326,9 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 let elided =
                     l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_)));
                 let lifetime = if elided { None } else { Some(l.clean(cx)) };
-                BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(m.ty.clean(cx)) }
+                BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
             }
-            TyKind::Slice(ref ty) => Slice(Box::new(ty.clean(cx))),
+            TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
             TyKind::Array(ref ty, ref length) => {
                 let def_id = cx.tcx.hir().local_def_id(length.hir_id);
                 // NOTE(min_const_generics): We can't use `const_eval_poly` for constants
@@ -1341,7 +1341,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 let ct = ty::Const::from_anon_const(cx.tcx, def_id);
                 let param_env = cx.tcx.param_env(def_id);
                 let length = print_const(cx, ct.eval(cx.tcx, param_env));
-                Array(Box::new(ty.clean(cx)), length)
+                Array(box ty.clean(cx), length)
             }
             TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
             TyKind::OpaqueDef(item_id, _) => {
@@ -1358,7 +1358,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None };
                 DynTrait(bounds, lifetime)
             }
-            TyKind::BareFn(ref barefn) => BareFunction(Box::new(barefn.clean(cx))),
+            TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
             TyKind::Infer | TyKind::Err => Infer,
             TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind),
@@ -1409,29 +1409,27 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
             ty::Uint(uint_ty) => Primitive(uint_ty.into()),
             ty::Float(float_ty) => Primitive(float_ty.into()),
             ty::Str => Primitive(PrimitiveType::Str),
-            ty::Slice(ty) => Slice(Box::new(ty.clean(cx))),
+            ty::Slice(ty) => Slice(box ty.clean(cx)),
             ty::Array(ty, n) => {
                 let mut n = cx.tcx.lift(n).expect("array lift failed");
                 n = n.eval(cx.tcx, ty::ParamEnv::reveal_all());
                 let n = print_const(cx, n);
-                Array(Box::new(ty.clean(cx)), n)
+                Array(box ty.clean(cx), n)
+            }
+            ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)),
+            ty::Ref(r, ty, mutbl) => {
+                BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) }
             }
-            ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(mt.ty.clean(cx))),
-            ty::Ref(r, ty, mutbl) => BorrowedRef {
-                lifetime: r.clean(cx),
-                mutability: mutbl,
-                type_: Box::new(ty.clean(cx)),
-            },
             ty::FnDef(..) | ty::FnPtr(_) => {
                 let ty = cx.tcx.lift(*self).expect("FnPtr lift failed");
                 let sig = ty.fn_sig(cx.tcx);
                 let def_id = DefId::local(CRATE_DEF_INDEX);
-                BareFunction(Box::new(BareFunctionDecl {
+                BareFunction(box BareFunctionDecl {
                     unsafety: sig.unsafety(),
                     generic_params: Vec::new(),
                     decl: (def_id, sig).clean(cx),
                     abi: sig.abi(),
-                }))
+                })
             }
             ty::Adt(def, substs) => {
                 let did = def.did;
@@ -1442,12 +1440,12 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 };
                 inline::record_extern_fqn(cx, did, kind);
                 let path = external_path(cx, did, false, vec![], substs);
-                ResolvedPath { path, did, is_generic: false }
+                ResolvedPath { path, did }
             }
             ty::Foreign(did) => {
                 inline::record_extern_fqn(cx, did, ItemType::ForeignType);
                 let path = external_path(cx, did, false, vec![], InternalSubsts::empty());
-                ResolvedPath { path, did, is_generic: false }
+                ResolvedPath { path, did }
             }
             ty::Dynamic(ref obj, ref reg) => {
                 // HACK: pick the first `did` as the `did` of the trait object. Someone
@@ -1473,7 +1471,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                     let path = external_path(cx, did, false, vec![], empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
                     let bound = PolyTrait {
-                        trait_: ResolvedPath { path, did, is_generic: false },
+                        trait_: ResolvedPath { path, did },
                         generic_params: Vec::new(),
                     };
                     bounds.push(bound);
@@ -1490,10 +1488,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                 let path = external_path(cx, did, false, bindings, substs);
                 bounds.insert(
                     0,
-                    PolyTrait {
-                        trait_: ResolvedPath { path, did, is_generic: false },
-                        generic_params: Vec::new(),
-                    },
+                    PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
                 );
 
                 DynTrait(bounds, lifetime)
@@ -1974,10 +1969,10 @@ fn clean_extern_crate(
     // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
     vec![Item {
         name: Some(name),
-        attrs: Box::new(attrs.clean(cx)),
+        attrs: box attrs.clean(cx),
         def_id: crate_def_id.into(),
         visibility: krate.vis.clean(cx),
-        kind: Box::new(ExternCrateItem { src: orig_name }),
+        kind: box ExternCrateItem { src: orig_name },
         cfg: attrs.cfg(cx.sess()),
     }]
 }
index b3c320555f9e53e08e030134b440432ed4722cab..fb2183ff2291b83707be86454c0ff4e80708e08e 100644 (file)
@@ -421,7 +421,7 @@ pub fn from_def_id_and_parts(
             def_id,
             name,
             kind,
-            Box::new(ast_attrs.clean(cx)),
+            box ast_attrs.clean(cx),
             cx,
             ast_attrs.cfg(cx.sess()),
         )
@@ -439,7 +439,7 @@ pub fn from_def_id_and_attrs_and_parts(
 
         Item {
             def_id: def_id.into(),
-            kind: Box::new(kind),
+            kind: box kind,
             name,
             attrs,
             visibility: cx.tcx.visibility(def_id).clean(cx),
@@ -1114,10 +1114,7 @@ impl GenericBound {
         let path = external_path(cx, did, false, vec![], empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
-            PolyTrait {
-                trait_: ResolvedPath { path, did, is_generic: false },
-                generic_params: Vec::new(),
-            },
+            PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
             hir::TraitBoundModifier::Maybe,
         )
     }
@@ -1384,8 +1381,6 @@ fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
     ResolvedPath {
         path: Path,
         did: DefId,
-        /// `true` if is a `T::Name` path for associated types.
-        is_generic: bool,
     },
     /// `dyn for<'a> Trait<'a> + Send + 'static`
     DynTrait(Vec<PolyTrait>, Option<Lifetime>),
@@ -1503,9 +1498,10 @@ impl Type {
         }
     }
 
-    crate fn is_generic(&self) -> bool {
-        match *self {
-            ResolvedPath { is_generic, .. } => is_generic,
+    /// Checks if this is a `T::Name` path for an associated type.
+    crate fn is_assoc_ty(&self) -> bool {
+        match self {
+            ResolvedPath { path, .. } => path.is_assoc_ty(),
             _ => false,
         }
     }
@@ -1994,6 +1990,16 @@ impl Path {
         String::from(if self.global { "::" } else { "" })
             + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
     }
+
+    /// Checks if this is a `T::Name` path for an associated type.
+    crate fn is_assoc_ty(&self) -> bool {
+        match self.res {
+            Res::SelfTy(..) if self.segments.len() != 1 => true,
+            Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true,
+            Res::Def(DefKind::AssocTy, _) => true,
+            _ => false,
+        }
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
index b0021d1234cd610ecdabb6494631ef10624dcffd..33d460d587a5176e8727c272dd5acdf873d820e7 100644 (file)
@@ -159,9 +159,7 @@ pub(super) fn external_path(
 
 crate fn strip_type(ty: Type) -> Type {
     match ty {
-        Type::ResolvedPath { path, did, is_generic } => {
-            Type::ResolvedPath { path: strip_path(&path), did, is_generic }
-        }
+        Type::ResolvedPath { path, did } => Type::ResolvedPath { path: strip_path(&path), did },
         Type::DynTrait(mut bounds, lt) => {
             let first = bounds.remove(0);
             let stripped_trait = strip_type(first.trait_);
@@ -404,19 +402,15 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: &'tcx ty::Const<'tc
 crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
     debug!("resolve_type({:?})", path);
 
-    let is_generic = match path.res {
-        Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
-        Res::SelfTy(..) if path.segments.len() == 1 => {
-            return Generic(kw::SelfUpper);
-        }
-        Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
-            return Generic(path.segments[0].name);
+    match path.res {
+        Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
+        Res::SelfTy(..) if path.segments.len() == 1 => Generic(kw::SelfUpper),
+        Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
+        _ => {
+            let did = register_res(cx, path.res);
+            ResolvedPath { path, did }
         }
-        Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
-        _ => false,
-    };
-    let did = register_res(cx, path.res);
-    ResolvedPath { path, did, is_generic }
+    }
 }
 
 crate fn get_auto_trait_and_blanket_impls(
index 765c77d5646cc7cd70ca0e8597eb3b1ca3a621a2..ddbe68762ee041b6bc3ffdf34d1ee0f6157b7433 100644 (file)
@@ -263,7 +263,7 @@ impl<'tcx> DocContext<'tcx> {
         stderr: None,
         lint_caps,
         parse_sess_created: None,
-        register_lints: Some(Box::new(crate::lint::register_lints)),
+        register_lints: Some(box crate::lint::register_lints),
         override_queries: Some(|_sess, providers, _external_providers| {
             // Most lints will require typechecking, so just don't run them.
             providers.lint_mod = |_, _| {};
index dbeea9cddf3879af8b2ac43683d6e89dac7e199b..ac760fad103c18d52138ba6b51b8bbeee0724755 100644 (file)
@@ -99,7 +99,7 @@
         stderr: None,
         lint_caps,
         parse_sess_created: None,
-        register_lints: Some(Box::new(crate::lint::register_lints)),
+        register_lints: Some(box crate::lint::register_lints),
         override_queries: None,
         make_codegen_backend: None,
         registry: rustc_driver::diagnostics_registry(),
@@ -550,10 +550,10 @@ fn drop(&mut self) {
                     .supports_color();
 
             let emitter =
-                EmitterWriter::new(Box::new(io::sink()), None, false, false, false, None, false);
+                EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
 
             // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
-            let handler = Handler::with_emitter(false, None, Box::new(emitter));
+            let handler = Handler::with_emitter(false, None, box emitter);
             let sess = ParseSess::with_span_handler(handler, sm);
 
             let mut found_main = false;
@@ -963,7 +963,7 @@ fn add_test(&mut self, test: String, config: LangString, line: usize) {
                 no_run,
                 test_type: test::TestType::DocTest,
             },
-            testfn: test::DynTestFn(Box::new(move || {
+            testfn: test::DynTestFn(box move || {
                 let report_unused_externs = |uext| {
                     unused_externs.lock().unwrap().push(uext);
                 };
@@ -1043,9 +1043,9 @@ fn add_test(&mut self, test: String, config: LangString, line: usize) {
                         }
                     }
 
-                    panic::resume_unwind(Box::new(()));
+                    panic::resume_unwind(box ());
                 }
-            })),
+            }),
         });
     }
 
index b4859e4c9c7fe2e10340f66df721dc7ef9214e3d..f84850c0fe1f1c1531ccd4b59d06698fa516cebb 100644 (file)
@@ -2,7 +2,7 @@
 
 crate fn strip_item(mut item: Item) -> Item {
     if !matches!(*item.kind, StrippedItem(..)) {
-        item.kind = Box::new(StrippedItem(item.kind));
+        item.kind = box StrippedItem(item.kind);
     }
     item
 }
@@ -69,10 +69,10 @@ fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind {
 
     /// don't override!
     fn fold_item_recur(&mut self, mut item: Item) -> Item {
-        item.kind = Box::new(match *item.kind {
-            StrippedItem(box i) => StrippedItem(Box::new(self.fold_inner_recur(i))),
+        item.kind = box match *item.kind {
+            StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
             _ => self.fold_inner_recur(*item.kind),
-        });
+        };
         item
     }
 
index 2fde0017dc80c63be5cb8a1ffc6728620da667f9..d11781581a8df6c61daa151e3d22eb257bd1899f 100644 (file)
@@ -752,9 +752,9 @@ fn fmt_type<'cx>(
 
     match *t {
         clean::Generic(name) => write!(f, "{}", name),
-        clean::ResolvedPath { did, ref path, is_generic } => {
+        clean::ResolvedPath { did, ref path } => {
             // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
-            resolved_path(f, did, path, is_generic, use_absolute, cx)
+            resolved_path(f, did, path, path.is_assoc_ty(), use_absolute, cx)
         }
         clean::DynTrait(ref bounds, ref lt) => {
             f.write_str("dyn ")?;
@@ -825,28 +825,17 @@ fn fmt_type<'cx>(
                 hir::Mutability::Mut => "mut",
                 hir::Mutability::Not => "const",
             };
-            match **t {
-                clean::Generic(_) | clean::ResolvedPath { is_generic: true, .. } => {
-                    if f.alternate() {
-                        primitive_link(
-                            f,
-                            clean::PrimitiveType::RawPointer,
-                            &format!("*{} {:#}", m, t.print(cx)),
-                            cx,
-                        )
-                    } else {
-                        primitive_link(
-                            f,
-                            clean::PrimitiveType::RawPointer,
-                            &format!("*{} {}", m, t.print(cx)),
-                            cx,
-                        )
-                    }
-                }
-                _ => {
-                    primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m), cx)?;
-                    fmt::Display::fmt(&t.print(cx), f)
-                }
+
+            if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
+                let text = if f.alternate() {
+                    format!("*{} {:#}", m, t.print(cx))
+                } else {
+                    format!("*{} {}", m, t.print(cx))
+                };
+                primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx)
+            } else {
+                primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m), cx)?;
+                fmt::Display::fmt(&t.print(cx), f)
             }
         }
         clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
index 52505f2d634717fa70f06a43f59d0a528a24b0f7..8888b42d948cd0bb072c406ac8f5724cf5df304e 100644 (file)
@@ -712,11 +712,10 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
         let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
         for implementor in implementors {
             match implementor.inner_impl().for_ {
-                clean::ResolvedPath { ref path, did, is_generic: false, .. }
+                clean::ResolvedPath { ref path, did, .. }
                 | clean::BorrowedRef {
-                    type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
-                    ..
-                } => {
+                    type_: box clean::ResolvedPath { ref path, did, .. }, ..
+                } if !path.is_assoc_ty() => {
                     let &mut (prev_did, ref mut has_duplicates) =
                         implementor_dups.entry(path.last()).or_insert((did, false));
                     if prev_did != did {
@@ -1410,11 +1409,12 @@ fn render_implementor(
     // If there's already another implementor that has the same abridged name, use the
     // full path, for example in `std::iter::ExactSizeIterator`
     let use_absolute = match implementor.inner_impl().for_ {
-        clean::ResolvedPath { ref path, is_generic: false, .. }
-        | clean::BorrowedRef {
-            type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
-            ..
-        } => implementor_dups[&path.last()].1,
+        clean::ResolvedPath { ref path, .. }
+        | clean::BorrowedRef { type_: box clean::ResolvedPath { ref path, .. }, .. }
+            if !path.is_assoc_ty() =>
+        {
+            implementor_dups[&path.last()].1
+        }
         _ => false,
     };
     render_impl(
@@ -1663,7 +1663,7 @@ fn write_size_of_layout(w: &mut Buffer, layout: &Layout, tag_size: u64) {
             writeln!(
                 w,
                 "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \
-                 completely unstable and may be different between compiler versions and platforms. \
+                 <strong>completely unstable</strong> and may even differ between compilations. \
                  The only exception is types with certain <code>repr(...)</code> attributes. \
                  Please see the Rust Reference’s \
                  <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \
index f8ea7a499b2340a4dcbd14e991d3f6131a1ba409..fda9070305797ad417e811466eb329380b924d27 100644 (file)
@@ -387,7 +387,7 @@ impl FromWithTcx<clean::Type> for Type {
     fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
         use clean::Type::*;
         match ty {
-            ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath {
+            ResolvedPath { path, did } => Type::ResolvedPath {
                 name: path.whole_name(),
                 id: from_item_id(did.into()),
                 args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
index f170561300cc2d6ef780b4ce0dde10286ab2aa00..5cfd21046f5d7748f64c2f5a034e848939f12077 100644 (file)
@@ -7,6 +7,7 @@
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
+#![feature(box_syntax)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(test)]
index c0c37ee061198573e3cacc768966215563edaba5..318c897bcbdf6f1c395effdc447d09cd689f1a16 100644 (file)
@@ -64,7 +64,7 @@ enum ErrorKind<'a> {
 
 impl<'a> From<ResolutionFailure<'a>> for ErrorKind<'a> {
     fn from(err: ResolutionFailure<'a>) -> Self {
-        ErrorKind::Resolve(Box::new(err))
+        ErrorKind::Resolve(box err)
     }
 }
 
@@ -759,7 +759,7 @@ fn traits_implemented_by(cx: &mut DocContext<'_>, type_: DefId, module: DefId) -
     let mut resolver = cx.resolver.borrow_mut();
     let in_scope_traits = cx.module_trait_cache.entry(module).or_insert_with(|| {
         resolver.access(|resolver| {
-            let parent_scope = &ParentScope::module(resolver.get_module(module), resolver);
+            let parent_scope = &ParentScope::module(resolver.expect_module(module), resolver);
             resolver
                 .traits_in_scope(None, parent_scope, SyntaxContext::root(), None)
                 .into_iter()
index a93880453ba274916cca5561235e5179ac9da166..90300dbd16b136261991b283abfeda085b8f6578 100644 (file)
@@ -128,7 +128,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
                 return None;
             }
             if let Some(did) = imp.for_.def_id() {
-                if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did.into())
+                if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
                 {
                     debug!("ImplStripper: impl item for stripped type; removing");
                     return None;
index 86c7daa627aefda1371568b948eba21edf720747..cba558df777a045b5657d56c29944e9e8fd3a776 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 86c7daa627aefda1371568b948eba21edf720747
+Subproject commit cba558df777a045b5657d56c29944e9e8fd3a776
index a692f6f896da724e69c4e4ec24163bc0e4ab1ec8..d60699efd36cb29aeb55e650a2b1211ba72938d8 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc-json-types"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [lib]
 path = "lib.rs"
diff --git a/src/test/assembly/x86_64-sse_crc.rs b/src/test/assembly/x86_64-sse_crc.rs
new file mode 100644 (file)
index 0000000..cdbf057
--- /dev/null
@@ -0,0 +1,12 @@
+// only-x86_64
+// assembly-output: emit-asm
+// compile-flags: --crate-type staticlib -Ctarget-feature=+sse4.2
+
+// CHECK-LABEL: banana
+// CHECK: crc32
+#[no_mangle]
+pub unsafe fn banana(v: u8) -> u32 {
+    use std::arch::x86_64::*;
+    let out = !0u32;
+    _mm_crc32_u8(out, v)
+}
index 8b0448ec470851d9a8f6e41878745158471829c0..c73d2a10a967bd3911425714e414af06864a340e 100644 (file)
@@ -1,9 +1,10 @@
 //
 
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
 // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/extern-drop-glue
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus -Copt-level=0
 
 #![allow(dead_code)]
index c96df6e102ac3391e2773063aae6a6f3b475a626..638ec079a0bce75a454e29f37fdf4e72f984cc2f 100644 (file)
@@ -1,7 +1,8 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/extern-generic -Zshare-generics=y
+// incremental
+// compile-flags:-Zprint-mono-items=eager -Zshare-generics=y
 
 #![allow(dead_code)]
 #![crate_type="lib"]
index 91ae6022931980c07e21b2da8a6dae90f504550a..118b7bdf4da8b9ee0c7a6508cf17089fd6b134a1 100644 (file)
@@ -1,6 +1,7 @@
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/incremental-merging
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Ccodegen-units=3
 
 #![crate_type = "rlib"]
index b86e325537b8171cc08ae3a2c9abdd02950401f1..1cc21632e4818ff8b6980ae76102a97b47baa349 100644 (file)
@@ -1,7 +1,8 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/inlining-from-extern-crate
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus
 
 #![crate_type="lib"]
index 78d69fdb7d814ff9f6fefa6f381c3d920200712f..2fd853a44b8ffc12d97d6d0342e426bf10ee0fee 100644 (file)
@@ -1,8 +1,9 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
 // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-drop-glue
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus -Copt-level=0
 
 #![allow(dead_code)]
index 9a7743bbf4686c17760c61df4a4c9e5f174e8b70..38aec7291df3f45817157a5f9d415493bb9bbe18 100644 (file)
@@ -1,6 +1,7 @@
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/local-generic
+// incremental
+// compile-flags:-Zprint-mono-items=eager
 
 #![allow(dead_code)]
 #![crate_type="lib"]
index d53f7b622913221c17b65835399616ef29ee86e9..318f0c28a5981a4a44cde8fb580cf2f15de2b111 100644 (file)
@@ -1,7 +1,8 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-inlining-but-not-all
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus=no
 
 #![allow(dead_code)]
index 1ea804b2f9d82c5beed1800ae4609b0f319bb7d9..841a428e9dd2ffb9ef0f473737571a89b7b259a9 100644 (file)
@@ -1,7 +1,8 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-inlining
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus
 
 #![allow(dead_code)]
index 56d108074e40d0ebacbe046a0df623de190a9e99..03c37954d151363e2252e156cc9c2c1f104ab012 100644 (file)
@@ -1,7 +1,8 @@
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-transitive-inlining
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus
 
 #![allow(dead_code)]
index e67090303a36387892dae17e809b690bcae1edc0..8220dc12ee0c6ac7dc44f4258edda4e8e45dc997 100644 (file)
@@ -4,9 +4,10 @@
 // ignore-test
 
 //
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/methods-are-with-self-type
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 
 #![allow(dead_code)]
 #![feature(start)]
index f9b8f52b0bb9e7fe0aae9f8fbea48ff2ba080d42..ce7fe9c3a4ff3ae4c1fe30fed39c774d4f329315 100644 (file)
@@ -1,6 +1,7 @@
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/regular-modules
+// incremental
+// compile-flags:-Zprint-mono-items=eager
 
 #![allow(dead_code)]
 #![crate_type="lib"]
index 17c1fbb2f739b13fb723e1d97a9f65be8229389c..ebe96bfb746af1962dcad076d453324b837f445e 100644 (file)
@@ -2,7 +2,8 @@
 // no-prefer-dynamic
 // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
 //       prevent drop-glue from participating in share-generics.
-// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Cincremental=tmp/partitioning-tests/shared-generics-exe -Copt-level=0
+// incremental
+// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Copt-level=0
 
 #![crate_type="rlib"]
 
index 02d6467577f4c0674fc39f45f5fc45fe3bc90122..b11d6696dc00ad80288c5d78b0cc93f8d4163b7c 100644 (file)
@@ -1,6 +1,7 @@
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/statics
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 
 #![crate_type="rlib"]
 
index f6ae46b0551c28fd76cf7fa76d8541e02909ed5f..cedcca804b36581722e5c75e3d256ec64b2114b9 100644 (file)
@@ -1,8 +1,9 @@
 //
 
-// We specify -C incremental here because we want to test the partitioning for
+// We specify incremental here because we want to test the partitioning for
 // incremental compilation
-// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/vtable-through-const
+// incremental
+// compile-flags:-Zprint-mono-items=lazy
 // compile-flags:-Zinline-in-all-cgus
 
 // This test case makes sure, that references made through constants are
index 62d093507ddeed0be61ff029e3a0c7a46d227b20..39f73c4e3967eff439afc494819ca778521d7a91 100644 (file)
@@ -1,8 +1,17 @@
-// compile-flags: -Z panic-in-drop=abort -O
+// compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no
 
 // Ensure that unwinding code paths are eliminated from the output after
 // optimization.
 
+// This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen
+// on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that
+// the drop_in_place() function can't unwind, but implements it in a way that *can*, because we
+// currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC
+// targets. We should either forbid longjmps, or not assume nounwind, making this optimization
+// incompatible with the current behavior of running cleanuppads on longjmp unwinding.
+
+// CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output
+
 #![crate_type = "lib"]
 use std::any::Any;
 use std::mem::forget;
@@ -35,8 +44,6 @@ fn drop(&mut self) {
     }
 }
 
-// CHECK-LABEL: normal_drop
-// CHECK-NOT: should_not_appear_in_output
 #[no_mangle]
 pub fn normal_drop(x: ExternDrop) {
     let guard = AssertNeverDrop;
@@ -44,8 +51,6 @@ pub fn normal_drop(x: ExternDrop) {
     forget(guard);
 }
 
-// CHECK-LABEL: indirect_drop
-// CHECK-NOT: should_not_appear_in_output
 #[no_mangle]
 pub fn indirect_drop(x: Box<dyn Any>) {
     let guard = AssertNeverDrop;
diff --git a/src/test/codegen/sse42-implies-crc32.rs b/src/test/codegen/sse42-implies-crc32.rs
new file mode 100644 (file)
index 0000000..47b1a89
--- /dev/null
@@ -0,0 +1,16 @@
+// only-x86_64
+// min-llvm-version: 14.0
+// compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+#[cfg(target_arch = "x86_64")]
+#[target_feature(enable = "sse4.2")]
+#[no_mangle]
+pub unsafe fn crc32sse(v: u8) -> u32 {
+    use std::arch::x86_64::*;
+    let out = !0u32;
+    _mm_crc32_u8(out, v)
+}
+
+// CHECK: attributes #0 {{.*"target-features"="\+sse4.2,\+crc32"}}
index 7f97d96b8db93a2cf50bcd2fc1192d8174b04d06..fe945266b13ca8a64caf164bfe80a7237d6ff618 100644 (file)
@@ -63,7 +63,6 @@
 // lldbr-check:(f64) *unique_val_interior_ref_2 = 26.5
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -79,7 +78,7 @@ fn main() {
     let stack_val_interior_ref_2: &f64 = &stack_val.y;
     let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
 
-    let unique_val: Box<_> = box SomeStruct { x: 13, y: 26.5 };
+    let unique_val: Box<_> = Box::new(SomeStruct { x: 13, y: 26.5 });
     let unique_val_ref: &SomeStruct = &*unique_val;
     let unique_val_interior_ref_1: &isize = &unique_val.x;
     let unique_val_interior_ref_2: &f64 = &unique_val.y;
index be4895ef5363e2907c97d7ea478d682346bc0dc8..cc28e49c4474550132137ebea5d620b0adb8865c 100644 (file)
@@ -37,7 +37,6 @@
 
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -46,7 +45,7 @@ fn main() {
     let stack_val_ref: &(i16, f32) = &stack_val;
     let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
 
-    let unique_val: Box<(i16, f32)> = box (-17, -22f32);
+    let unique_val: Box<(i16, f32)> = Box::new((-17, -22f32));
     let unique_val_ref: &(i16, f32) = &*unique_val;
 
     zzz(); // #break
index f927a54f02aa69688684678ba28d20b30b6b4daa..b39f24e029e31fc8942979c2d99a9471a9e636b9 100644 (file)
 // lldbr-check:(f64) *f64_ref = 3.5
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
 fn main() {
-    let bool_box: Box<bool> = box true;
+    let bool_box: Box<bool> = Box::new(true);
     let bool_ref: &bool = &*bool_box;
 
-    let int_box: Box<isize> = box -1;
+    let int_box: Box<isize> = Box::new(-1);
     let int_ref: &isize = &*int_box;
 
-    let char_box: Box<char> = box 'a';
+    let char_box: Box<char> = Box::new('a');
     let char_ref: &char = &*char_box;
 
-    let i8_box: Box<i8> = box 68;
+    let i8_box: Box<i8> = Box::new(68);
     let i8_ref: &i8 = &*i8_box;
 
-    let i16_box: Box<i16> = box -16;
+    let i16_box: Box<i16> = Box::new(-16);
     let i16_ref: &i16 = &*i16_box;
 
-    let i32_box: Box<i32> = box -32;
+    let i32_box: Box<i32> = Box::new(-32);
     let i32_ref: &i32 = &*i32_box;
 
-    let i64_box: Box<i64> = box -64;
+    let i64_box: Box<i64> = Box::new(-64);
     let i64_ref: &i64 = &*i64_box;
 
-    let uint_box: Box<usize> = box 1;
+    let uint_box: Box<usize> = Box::new(1);
     let uint_ref: &usize = &*uint_box;
 
-    let u8_box: Box<u8> = box 100;
+    let u8_box: Box<u8> = Box::new(100);
     let u8_ref: &u8 = &*u8_box;
 
-    let u16_box: Box<u16> = box 16;
+    let u16_box: Box<u16> = Box::new(16);
     let u16_ref: &u16 = &*u16_box;
 
-    let u32_box: Box<u32> = box 32;
+    let u32_box: Box<u32> = Box::new(32);
     let u32_ref: &u32 = &*u32_box;
 
-    let u64_box: Box<u64> = box 64;
+    let u64_box: Box<u64> = Box::new(64);
     let u64_ref: &u64 = &*u64_box;
 
-    let f32_box: Box<f32> = box 2.5;
+    let f32_box: Box<f32> = Box::new(2.5);
     let f32_ref: &f32 = &*f32_box;
 
-    let f64_box: Box<f64> = box 3.5;
+    let f64_box: Box<f64> = Box::new(3.5);
     let f64_ref: &f64 = &*f64_box;
 
     zzz(); // #break
index e443b67ebfb31a2803da32c1035a0e404df6b9c1..3713c8c135d2e6721ac2019306a6a4c730a80567 100644 (file)
 // lldbr-check:((i32, f64)) *b = { 0 = 2 1 = 3.5 }
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
 fn main() {
-    let a = box 1;
-    let b = box (2, 3.5f64);
+    let a = Box::new(1);
+    let b = Box::new((2, 3.5f64));
 
     zzz(); // #break
 }
index 155088c61fe3133b16a246a7beaddded0cf41b62..64bc124756d6dd23e54bc67a417fc3f6168f98db 100644 (file)
@@ -28,7 +28,6 @@
 // lldbr-check:(boxed_struct::StructWithDestructor) *boxed_with_dtor = { x = 77 y = 777 z = 7777 w = 77777 }
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -52,9 +51,19 @@ fn drop(&mut self) {}
 
 fn main() {
 
-    let boxed_with_padding: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
-
-    let boxed_with_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+    let boxed_with_padding: Box<_> = Box::new(StructWithSomePadding {
+        x: 99,
+        y: 999,
+        z: 9999,
+        w: 99999,
+    });
+
+    let boxed_with_dtor: Box<_> = Box::new(StructWithDestructor {
+        x: 77,
+        y: 777,
+        z: 7777,
+        w: 77777,
+    });
     zzz(); // #break
 }
 
index 239055b3a78b63640471c9f776c10b6c71ed8a38..91d7ddc5416d8dcba6420a36afdfb0067c7bdd0e 100644 (file)
@@ -39,7 +39,6 @@
 // lldbr-check:(i32) *y = 110
 // lldb-command:continue
 
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
index a776f51907158aadeb9e4f1bf727a87b06cef0e3..9cd3874a5dfb74aba31c0628d3720a44ddfcade0 100644 (file)
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -480,7 +479,7 @@ fn main() {
     managed_box(&(34, 35));
     borrowed_pointer(&(36, 37));
     contained_borrowed_pointer((&38, 39));
-    unique_pointer(box (40, 41, 42));
+    unique_pointer(Box::new((40, 41, 42)));
     ref_binding((43, 44, 45));
     ref_binding_in_tuple((46, (47, 48)));
     ref_binding_in_struct(Struct { a: 49, b: 50 });
index 1532c83dfac3a849c99578b202eca7d945425ab3..15cb88ef25d5b437dfca0a9ed1f92be30e9c5834 100644 (file)
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -214,7 +213,7 @@ fn main() {
             y: -300001.5,
             z: true
          },
-         box 854237.5);
+         Box::new(854237.5));
 
     for &(v1,
           &Struct { x: x1, y: ref y1, z: z1 },
index 712168b5baa870ad6de9cd056cbf2f7e7bbc5da5..3a2a889777ea0f87ce1935583d18c3069b73b9c8 100644 (file)
 
 #![allow(unused_variables)]
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -345,7 +344,7 @@ fn main() {
     let (&cc, _) = (&38, 39);
 
     // unique pointer
-    let box dd = box (40, 41, 42);
+    let box dd = Box::new((40, 41, 42));
 
     // ref binding
     let ref ee = (43, 44, 45);
index 85fe8ac08f3c48241b57ef7bf8f5ef3992a6a7dc..97609ef5d9341e249869301215f3cea39613c32c 100644 (file)
 // lldbr-check:(f32) arg2 = -10.5
 // lldb-command:continue
 
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -155,7 +154,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, 2_u16);
     let _ = stack.self_by_val(-3, -4_i16);
 
-    let owned: Box<_> = box Struct { x: 1234.5f64 };
+    let owned: Box<_> = Box::new(Struct { x: 1234.5f64 });
     let _ = owned.self_by_ref(-5, -6_i32);
     let _ = owned.self_by_val(-7, -8_i64);
     let _ = owned.self_owned(-9, -10.5_f32);
index 80f4c2e1150ec50d89b6b895569eb1fcdfb66f85..aaa9bd9d6f97ad3084d35fff8b923451ad903c76 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -140,7 +139,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box Enum::Variant1{ x: 1799, y: 1799 };
+    let owned: Box<_> = Box::new(Enum::Variant1{ x: 1799, y: 1799 });
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
index 80cbf7430ca6e8885f0ac121e4128683a6453d5b..bf047449164b000fa850599447dd8c3fe0a22f89 100644 (file)
 // lldbr-check:(isize) arg2 = -10
 // lldb-command:continue
 
-
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -156,7 +154,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box Struct { x: 1234.5f64 };
+    let owned: Box<_> = Box::new(Struct { x: 1234.5f64 });
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
index c764cf68323786672408c4656e6dbfe74df8110c..deed4f9cc0ad989920044fc134099ebc9ae89658 100644 (file)
 // lldbr-check:(isize) arg2 = -10
 // lldb-command:continue
 
-
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -154,7 +152,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box Struct { x: 200 };
+    let owned: Box<_> = Box::new(Struct { x: 200 });
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
index 6dcf28967776fabe12aca64c0c3b8f337ed61767..7ebebfa72b92bbbd20d3ab25b5b12ea9bf3ef1cd 100644 (file)
 // lldbr-check:(isize) arg2 = -10
 // lldb-command:continue
 
-
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -160,7 +158,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box Struct { x: 200 };
+    let owned: Box<_> = Box::new(Struct { x: 200 });
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
index d06b606e973e8e5b5f0a263427285069f62d4188..a5a87b2ad6f26b738dbb87fbd54f2269a4fce05a 100644 (file)
 // lldbr-check:(isize) arg2 = -10
 // lldb-command:continue
 
-
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -152,7 +150,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box TupleStruct(200, -200.5);
+    let owned: Box<_> = Box::new(TupleStruct(200, -200.5));
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
new file mode 100644 (file)
index 0000000..3846fb4
--- /dev/null
@@ -0,0 +1,101 @@
+// only-cdb
+// compile-flags: -g
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1               : (0xa..0xc) [Type: core::ops::range::Range<u32>]
+// cdb-command: dx r2
+// cdb-check:r2               : (0x14..0x1e) [Type: core::ops::range::Range<u64>]
+
+// cdb-command: g
+
+// cdb-command: dx r1
+// cdb-check:r1               : (0x9..0x64) [Type: core::ops::range::Range<u32>]
+// cdb-command: dx r2
+// cdb-check:r2               : (0xc..0x5a) [Type: core::ops::range::Range<u64>]
+
+// cdb-command: g
+
+// cdb-command: dx o1
+// cdb-check:o1               : Some [Type: enum$<core::option::Option<u32> >]
+// cdb-check:    [variant]        : Some
+// cdb-check:    [+0x004] __0              : 0x4d2 [Type: [...]]
+// cdb-command: dx o2
+// cdb-check:o2               : Some [Type: enum$<core::option::Option<u64> >]
+// cdb-check:    [variant]        : Some
+// cdb-check:    [+0x008] __0              : 0x162e [Type: unsigned __int64]
+
+// cdb-command: g
+
+// cdb-command: dx t1
+// cdb-check:t1               : (0xa, 0x14) [Type: tuple$<u32,u32>]
+// cdb-check:    [0]              : 0xa [Type: unsigned int]
+// cdb-check:    [1]              : 0x14 [Type: unsigned int]
+// cdb-command: dx t2
+// cdb-check:t2               : (0x1e, 0x28) [Type: tuple$<u64,u64>]
+// cdb-check:    [0]              : 0x1e [Type: unsigned __int64]
+// cdb-check:    [1]              : 0x28 [Type: unsigned __int64]
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s                : "this is a static str" [Type: str]
+// cdb-check:    [len]            : 0x14 [Type: unsigned [...]]
+// cdb-check:    [chars]
+
+// cdb-command: g
+
+// cdb-command: dx s
+// cdb-check:s                : { len=0x5 } [Type: slice$<u8>]
+// cdb-check:    [len]            : 0x5 [Type: unsigned [...]]
+// cdb-check:    [0]              : 0x1 [Type: unsigned char]
+// cdb-check:    [1]              : 0x2 [Type: unsigned char]
+// cdb-check:    [2]              : 0x3 [Type: unsigned char]
+// cdb-check:    [3]              : 0x4 [Type: unsigned char]
+// cdb-check:    [4]              : 0x5 [Type: unsigned char]
+
+use std::ops::Range;
+
+fn range(r1: Range<u32>, r2: Range<u64>) {
+    zzz(); // #break
+}
+
+fn range_mut(mut r1: Range<u32>, mut r2: Range<u64>) {
+    if r1.start == 9 {
+        r1.end = 100;
+    }
+
+    if r2.start == 12 {
+        r2.end = 90;
+    }
+
+    zzz(); // #break
+}
+
+fn option(o1: Option<u32>, o2: Option<u64>) {
+    zzz(); // #break
+}
+
+fn tuple(t1: (u32, u32), t2: (u64, u64)) {
+    zzz(); // #break
+}
+
+fn str(s: &str) {
+    zzz(); // #break
+}
+
+fn slice(s: &[u8]) {
+    zzz(); // #break
+}
+
+fn zzz() { }
+
+fn main() {
+    range(10..12, 20..30);
+    range_mut(9..20, 12..80);
+    option(Some(1234), Some(5678));
+    tuple((10, 20), (30, 40));
+    str("this is a static str");
+    slice(&[1, 2, 3, 4, 5]);
+}
index 4a529541bae60734236b0d380a72aa074a526fd0..00dccf5f9064a3dfa00f9d2d98c59dc5ed82e436 100644 (file)
@@ -3,8 +3,6 @@
 // cdb-only
 // min-cdb-version: 10.0.21287.1005
 // compile-flags:-g
-// FIXME: Failed on update to 10.0.22000.1
-// ignore-windows
 
 // === CDB TESTS ==================================================================================
 //
 // cdb-check:m,d              [Type: std::sync::mutex::Mutex<i32>]
 // cdb-check:    [...] inner            [Type: std::sys_common::mutex::MovableMutex]
 // cdb-check:    [...] poison           [Type: std::sync::poison::Flag]
-// cdb-check:    [...] data             [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] data             : 0 [Type: core::cell::UnsafeCell<i32>]
 
 //
 // cdb-command:dx m.data,d
-// cdb-check:m.data,d         [Type: core::cell::UnsafeCell<i32>]
-// cdb-check:    [...] value            : 0 [Type: int]
+// cdb-check:m.data,d         : 0 [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [<Raw View>]     [Type: core::cell::UnsafeCell<i32>]
 
 //
 // cdb-command:dx lock,d
-// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>, enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
-// cdb-check:    [...] variant$         : Ok (0) [Type: core::result::Result]
+// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
+// cdb-check:    [variant]        : Ok
 // cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]
 
 use std::sync::Mutex;
index c0bd67367012f51ad3bcc5735868fc54fe0df0ad..eb14af8c588ded436c0dbe349c00bf6cbb3b8de7 100644 (file)
 // gdb-command:print long_cycle4.value
 // gdb-check:$18 = 29.5
 
-// gdbr-command:print long_cycle_w_anonymous_types.value
+// gdbr-command:print long_cycle_w_anon_types.value
 // gdb-check:$19 = 30
 
-// gdbr-command:print long_cycle_w_anonymous_types.next.val.value
+// gdbr-command:print long_cycle_w_anon_types.next.val.value
 // gdb-check:$20 = 31
 
 // gdb-command:continue
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
 use self::Opt::{Empty, Val};
+use std::boxed::Box as B;
 
 enum Opt<T> {
     Empty,
@@ -120,75 +120,75 @@ struct LongCycleWithAnonymousTypes {
 fn main() {
     let stack_unique: UniqueNode<u16> = UniqueNode {
         next: Val {
-            val: box UniqueNode {
+            val: Box::new(UniqueNode {
                 next: Empty,
                 value: 1,
-            }
+            })
         },
         value: 0,
     };
 
-    let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
+    let unique_unique: Box<UniqueNode<u32>> = Box::new(UniqueNode {
         next: Val {
-            val: box UniqueNode {
+            val: Box::new(UniqueNode {
                 next: Empty,
                 value: 3,
-            }
+            })
         },
         value: 2,
-    };
+    });
 
     let vec_unique: [UniqueNode<f32>; 1] = [UniqueNode {
         next: Val {
-            val: box UniqueNode {
+            val: Box::new(UniqueNode {
                 next: Empty,
                 value: 7.5,
-            }
+            })
         },
         value: 6.5,
     }];
 
     let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
         next: Val {
-            val: box UniqueNode {
+            val: Box::new(UniqueNode {
                 next: Empty,
                 value: 9.5,
-            }
+            })
         },
         value: 8.5,
     };
 
     // LONG CYCLE
     let long_cycle1: LongCycle1<u16> = LongCycle1 {
-        next: box LongCycle2 {
-            next: box LongCycle3 {
-                next: box LongCycle4 {
+        next: Box::new(LongCycle2 {
+            next: Box::new(LongCycle3 {
+                next: Box::new(LongCycle4 {
                     next: None,
                     value: 23,
-                },
+                }),
                 value: 22,
-            },
+            }),
             value: 21
-        },
+        }),
         value: 20
     };
 
     let long_cycle2: LongCycle2<u32> = LongCycle2 {
-        next: box LongCycle3 {
-            next: box LongCycle4 {
+        next: Box::new(LongCycle3 {
+            next: Box::new(LongCycle4 {
                 next: None,
                 value: 26,
-            },
+            }),
             value: 25,
-        },
+        }),
         value: 24
     };
 
     let long_cycle3: LongCycle3<u64> = LongCycle3 {
-        next: box LongCycle4 {
+        next: Box::new(LongCycle4 {
             next: None,
             value: 28,
-        },
+        }),
         value: 27,
     };
 
@@ -199,15 +199,15 @@ fn main() {
 
     // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
     // `box` chain.
-    let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes {
+    let long_cycle_w_anon_types = B::new(B::new(B::new(B::new(B::new(LongCycleWithAnonymousTypes {
         next: Val {
-            val: box box box box box LongCycleWithAnonymousTypes {
+            val: Box::new(Box::new(Box::new(Box::new(Box::new(LongCycleWithAnonymousTypes {
                 next: Empty,
                 value: 31,
-            }
+            })))))
         },
         value: 30
-    };
+    })))));
 
     zzz(); // #break
 }
index e15c08577e15a7770e2ed527efea9eb9a297ec49..b8b5add0996aad7c3aee0c83b2ad931dc70fbbfa 100644 (file)
 // lldbr-check:(isize) arg2 = -10
 // lldb-command:continue
 
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -154,7 +153,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned: Box<_> = box Struct { x: 200 };
+    let owned: Box<_> = Box::new(Struct { x: 200 });
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
index 7634e3247d591a3465b8fcbe9080740bcd061696..efce449e312edb4b47920d0710ede5b2072a1a15 100644 (file)
 // lldbr-check:(f32) arg2 = -10.5
 // lldb-command:continue
 
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -155,7 +154,7 @@ fn main() {
     let _ = stack.self_by_ref(-1, 2_u16);
     let _ = stack.self_by_val(-3, -4_i16);
 
-    let owned: Box<_> = box Struct { x: 879 };
+    let owned: Box<_> = Box::new(Struct { x: 879 });
     let _ = owned.self_by_ref(-5, -6_i32);
     let _ = owned.self_by_val(-7, -8_i64);
     let _ = owned.self_owned(-9, -10.5_f32);
index a44f30abd6859378c3950dc3f8b11d3afccbcb43..e12daaf114e142c882d43cabce7cc46258c181b8 100644 (file)
@@ -5,7 +5,6 @@
 // lldb-command:run
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -24,5 +23,5 @@ impl Trait for Struct {}
 fn main() {
     let stack_struct = Struct { a:0, b: 1.0 };
     let reference: &Trait = &stack_struct as &Trait;
-    let unique: Box<Trait> = box Struct { a:2, b: 3.0 } as Box<Trait>;
+    let unique: Box<Trait> = Box::new(Struct { a:2, b: 3.0 }) as Box<Trait>;
 }
index 3497f0afb2cb0bd4447872ef8bb0ceb1f2d40111..2c10360fc924e94e3fe7cd8c6d48c0077d1eac1d 100644 (file)
 // cdb-check:struct ForeignType2 * foreign2 = [...]
 // cdb-check:struct ForeignType1 * foreign1 = [...]
 
-#![feature(box_syntax)]
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
@@ -373,8 +372,8 @@ fn main() {
     let tuple2 = ((Struct1, mod1::mod2::Struct3), mod1::Variant1, 'x');
 
     // Box
-    let box1 = (box 1f32, 0i32);
-    let box2 = (box mod1::mod2::Variant2(1f32), 0i32);
+    let box1 = (Box::new(1f32), 0i32);
+    let box2 = (Box::new(mod1::mod2::Variant2(1f32)), 0i32);
 
     // References
     let ref1 = (&Struct1, 0i32);
@@ -404,14 +403,14 @@ fn main() {
     let slice2 = &*vec2;
 
     // Trait Objects
-    let box_trait = (box 0_isize) as Box<dyn Trait1>;
+    let box_trait = Box::new(0_isize) as Box<dyn Trait1>;
     let ref_trait = &0_isize as &dyn Trait1;
     let mut mut_int1 = 0_isize;
     let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1;
-    let no_principal_trait = (box 0_isize) as Box<(dyn Send + Sync)>;
+    let no_principal_trait = Box::new(0_isize) as Box<(dyn Send + Sync)>;
     let has_associated_type_trait = &0_isize as &(dyn Trait3<u32, AssocType = isize> + Send);
 
-    let generic_box_trait = (box 0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
+    let generic_box_trait = Box::new(0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
     let generic_ref_trait = (&0_isize) as &dyn Trait2<Struct1, Struct1>;
 
     let mut generic_mut_ref_trait_impl = 0_isize;
index 9d938b6e36919f31f75efab60a220028321a98cb..d7dfaeefe2b7775114db63aea3fb32dc085628fa 100644 (file)
@@ -32,7 +32,6 @@
 // lldbr-check:(unique_enum::Univariant) *univariant = { TheOnlyCase = { = 123234 } }
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -59,15 +58,15 @@ fn main() {
     // 0b01111100011111000111110001111100 = 2088533116
     // 0b0111110001111100 = 31868
     // 0b01111100 = 124
-    let the_a: Box<_> = box ABC::TheA { x: 0, y: 8970181431921507452 };
+    let the_a: Box<_> = Box::new(ABC::TheA { x: 0, y: 8970181431921507452 });
 
     // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
     // 0b00010001000100010001000100010001 = 286331153
     // 0b0001000100010001 = 4369
     // 0b00010001 = 17
-    let the_b: Box<_> = box ABC::TheB (0, 286331153, 286331153);
+    let the_b: Box<_> = Box::new(ABC::TheB (0, 286331153, 286331153));
 
-    let univariant: Box<_> = box Univariant::TheOnlyCase(123234);
+    let univariant: Box<_> = Box::new(Univariant::TheOnlyCase(123234));
 
     zzz(); // #break
 }
index a2778fc6090d2bf77716bc59817bd59ed43f2848..d811915c38767ac202705fe3428f3173d14d202e 100644 (file)
 // cdb-check:closure_local    : 8 [Type: [...]]
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -154,7 +153,7 @@ fn main() {
     };
 
     let struct_ref = &a_struct;
-    let owned: Box<_> = box 6;
+    let owned: Box<_> = Box::new(6);
 
     let mut closure = || {
         let closure_local = 8;
index bd7c2bfe2c3ffb124bdb9435918779e18e454fa1..39930e04e4c5f5d88f94dcd572b9a571aa6438b6 100644 (file)
@@ -34,7 +34,6 @@
 // lldbr-check:(isize) *owned = 5
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -53,7 +52,7 @@ fn main() {
         c: 4
     };
 
-    let owned: Box<_> = box 5;
+    let owned: Box<_> = Box::new(5);
 
     let closure = move || {
         zzz(); // #break
index 1bbb79c37a4e70a58e93a782484c59246eff4064..d68409a9d5205fa8a0371055211de7fbdec91772 100644 (file)
 // cdb-command: dx owned
 // cdb-check:owned            : 0x[...] : 6 [Type: [...] *]
 
-#![feature(box_syntax)]
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
@@ -137,7 +136,7 @@ fn main() {
     };
 
     let struct_ref = &a_struct;
-    let owned: Box<_> = box 6;
+    let owned: Box<_> = Box::new(6);
 
     {
         let mut first_closure = || {
index 783407a9e04f1cf8ef9e8adbc5a33bf3ebc520d6..4bc98fd7cd08291f2e424120389383817d4882e3 100644 (file)
 // Make function public --------------------------------------------------------
 #[cfg(any(cfail1,cfail4))]
 extern "C" {
-    fn make_function_public(c: i32);
+    fn     make_function_public(c: i32);
 }
 
 #[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg = "cfail2", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
-#[rustc_clean(cfg = "cfail5", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail5")]
 #[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn make_function_public(c: i32);
index d711cc20dd70afd78bfac79fabfa79924a741880..3a59377e819694d12d946cbfd1d64a0d99b6e6e0 100644 (file)
@@ -116,20 +116,24 @@ pub fn method_body_inlined() {
 // Change Method Privacy -------------------------------------------------------
 #[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------
+    //--------------------------
     pub fn method_privacy() { }
 }
 
 #[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg="cfail2", except="hir_owner")]
+#[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
-#[rustc_clean(cfg="cfail5", except="hir_owner")]
+#[rustc_clean(cfg="cfail5")]
 #[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="associated_item,hir_owner,hir_owner_nodes")]
     #[rustc_clean(cfg="cfail3")]
-    #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes")]
     #[rustc_clean(cfg="cfail6")]
-    fn method_privacy() { }
+    fn     method_privacy() { }
 }
 
 // Change Method Selfness -----------------------------------------------------------
index cfbd3a58637c0edd08c958bf59739c1b9841d761..c6187879ab0a9cca0438a29de9cc8da6e9152ab9 100644 (file)
@@ -3,64 +3,78 @@
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/box_expr.rs:6:11: 6:11
     let _1: std::boxed::Box<S>;          // in scope 0 at $DIR/box_expr.rs:7:9: 7:10
-    let mut _2: std::boxed::Box<S>;      // in scope 0 at $DIR/box_expr.rs:7:13: 7:25
-    let _3: ();                          // in scope 0 at $DIR/box_expr.rs:8:5: 8:12
-    let mut _4: std::boxed::Box<S>;      // in scope 0 at $DIR/box_expr.rs:8:10: 8:11
+    let mut _2: usize;                   // in scope 0 at $DIR/box_expr.rs:7:13: 7:25
+    let mut _3: usize;                   // in scope 0 at $DIR/box_expr.rs:7:13: 7:25
+    let mut _4: *mut u8;                 // in scope 0 at $DIR/box_expr.rs:7:13: 7:25
+    let mut _5: std::boxed::Box<S>;      // in scope 0 at $DIR/box_expr.rs:7:13: 7:25
+    let _6: ();                          // in scope 0 at $DIR/box_expr.rs:8:5: 8:12
+    let mut _7: std::boxed::Box<S>;      // in scope 0 at $DIR/box_expr.rs:8:10: 8:11
     scope 1 {
         debug x => _1;                   // in scope 1 at $DIR/box_expr.rs:7:9: 7:10
     }
+    scope 2 {
+    }
 
     bb0: {
         StorageLive(_1);                 // scope 0 at $DIR/box_expr.rs:7:9: 7:10
-        StorageLive(_2);                 // scope 0 at $DIR/box_expr.rs:7:13: 7:25
-        _2 = Box(S);                     // scope 0 at $DIR/box_expr.rs:7:13: 7:25
-        (*_2) = S::new() -> [return: bb1, unwind: bb7]; // scope 0 at $DIR/box_expr.rs:7:17: 7:25
+        _2 = SizeOf(S);                  // scope 2 at $DIR/box_expr.rs:7:13: 7:25
+        _3 = AlignOf(S);                 // scope 2 at $DIR/box_expr.rs:7:13: 7:25
+        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/box_expr.rs:7:13: 7:25
                                          // mir::Constant
-                                         // + span: $DIR/box_expr.rs:7:17: 7:23
-                                         // + literal: Const { ty: fn() -> S {S::new}, val: Value(Scalar(<ZST>)) }
+                                         // + span: $DIR/box_expr.rs:7:13: 7:25
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        _1 = move _2;                    // scope 0 at $DIR/box_expr.rs:7:13: 7:25
-        drop(_2) -> bb2;                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
+        StorageLive(_5);                 // scope 0 at $DIR/box_expr.rs:7:13: 7:25
+        _5 = ShallowInitBox(move _4, S); // scope 0 at $DIR/box_expr.rs:7:13: 7:25
+        (*_5) = S::new() -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/box_expr.rs:7:17: 7:25
+                                         // mir::Constant
+                                         // + span: $DIR/box_expr.rs:7:17: 7:23
+                                         // + literal: Const { ty: fn() -> S {S::new}, val: Value(Scalar(<ZST>)) }
     }
 
     bb2: {
-        StorageDead(_2);                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
-        StorageLive(_3);                 // scope 1 at $DIR/box_expr.rs:8:5: 8:12
-        StorageLive(_4);                 // scope 1 at $DIR/box_expr.rs:8:10: 8:11
-        _4 = move _1;                    // scope 1 at $DIR/box_expr.rs:8:10: 8:11
-        _3 = std::mem::drop::<Box<S>>(move _4) -> [return: bb3, unwind: bb5]; // scope 1 at $DIR/box_expr.rs:8:5: 8:12
+        _1 = move _5;                    // scope 0 at $DIR/box_expr.rs:7:13: 7:25
+        drop(_5) -> bb3;                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
+    }
+
+    bb3: {
+        StorageDead(_5);                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
+        StorageLive(_6);                 // scope 1 at $DIR/box_expr.rs:8:5: 8:12
+        StorageLive(_7);                 // scope 1 at $DIR/box_expr.rs:8:10: 8:11
+        _7 = move _1;                    // scope 1 at $DIR/box_expr.rs:8:10: 8:11
+        _6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6]; // scope 1 at $DIR/box_expr.rs:8:5: 8:12
                                          // mir::Constant
                                          // + span: $DIR/box_expr.rs:8:5: 8:9
                                          // + literal: Const { ty: fn(std::boxed::Box<S>) {std::mem::drop::<std::boxed::Box<S>>}, val: Value(Scalar(<ZST>)) }
     }
 
-    bb3: {
-        StorageDead(_4);                 // scope 1 at $DIR/box_expr.rs:8:11: 8:12
-        StorageDead(_3);                 // scope 1 at $DIR/box_expr.rs:8:12: 8:13
+    bb4: {
+        StorageDead(_7);                 // scope 1 at $DIR/box_expr.rs:8:11: 8:12
+        StorageDead(_6);                 // scope 1 at $DIR/box_expr.rs:8:12: 8:13
         _0 = const ();                   // scope 0 at $DIR/box_expr.rs:6:11: 9:2
-        drop(_1) -> bb4;                 // scope 0 at $DIR/box_expr.rs:9:1: 9:2
+        drop(_1) -> bb5;                 // scope 0 at $DIR/box_expr.rs:9:1: 9:2
     }
 
-    bb4: {
+    bb5: {
         StorageDead(_1);                 // scope 0 at $DIR/box_expr.rs:9:1: 9:2
         return;                          // scope 0 at $DIR/box_expr.rs:9:2: 9:2
     }
 
-    bb5 (cleanup): {
-        drop(_4) -> bb6;                 // scope 1 at $DIR/box_expr.rs:8:11: 8:12
-    }
-
     bb6 (cleanup): {
-        drop(_1) -> bb8;                 // scope 0 at $DIR/box_expr.rs:9:1: 9:2
+        drop(_7) -> bb7;                 // scope 1 at $DIR/box_expr.rs:8:11: 8:12
     }
 
     bb7 (cleanup): {
-        drop(_2) -> bb8;                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
+        drop(_1) -> bb9;                 // scope 0 at $DIR/box_expr.rs:9:1: 9:2
     }
 
     bb8 (cleanup): {
+        drop(_5) -> bb9;                 // scope 0 at $DIR/box_expr.rs:7:24: 7:25
+    }
+
+    bb9 (cleanup): {
         resume;                          // scope 0 at $DIR/box_expr.rs:6:1: 9:2
     }
 }
index 9fcbd32ca686df22b7cd26cdbf06a6cd055f34d1..342c987343eac911b82231fad01546734c2c1a35 100644 (file)
@@ -6,34 +6,51 @@
       let _1: i32;                         // in scope 0 at $DIR/boxes.rs:12:9: 12:10
       let mut _2: i32;                     // in scope 0 at $DIR/boxes.rs:12:13: 12:22
       let mut _3: std::boxed::Box<i32>;    // in scope 0 at $DIR/boxes.rs:12:14: 12:22
-      let mut _4: std::boxed::Box<i32>;    // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _4: usize;                   // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _5: usize;                   // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _6: *mut u8;                 // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _7: std::boxed::Box<i32>;    // in scope 0 at $DIR/boxes.rs:12:14: 12:22
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/boxes.rs:12:9: 12:10
       }
+      scope 2 {
+      }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/boxes.rs:12:9: 12:10
           StorageLive(_2);                 // scope 0 at $DIR/boxes.rs:12:13: 12:22
           StorageLive(_3);                 // scope 0 at $DIR/boxes.rs:12:14: 12:22
-          StorageLive(_4);                 // scope 0 at $DIR/boxes.rs:12:14: 12:22
-          _4 = Box(i32);                   // scope 0 at $DIR/boxes.rs:12:14: 12:22
-          (*_4) = const 42_i32;            // scope 0 at $DIR/boxes.rs:12:19: 12:21
-          _3 = move _4;                    // scope 0 at $DIR/boxes.rs:12:14: 12:22
-          StorageDead(_4);                 // scope 0 at $DIR/boxes.rs:12:21: 12:22
+-         _4 = SizeOf(i32);                // scope 2 at $DIR/boxes.rs:12:14: 12:22
+-         _5 = AlignOf(i32);               // scope 2 at $DIR/boxes.rs:12:14: 12:22
+-         _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
++         _4 = const 4_usize;              // scope 2 at $DIR/boxes.rs:12:14: 12:22
++         _5 = const 4_usize;              // scope 2 at $DIR/boxes.rs:12:14: 12:22
++         _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
+                                           // mir::Constant
+                                           // + span: $DIR/boxes.rs:12:14: 12:22
+                                           // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageLive(_7);                 // scope 0 at $DIR/boxes.rs:12:14: 12:22
+          _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:12:14: 12:22
+          (*_7) = const 42_i32;            // scope 0 at $DIR/boxes.rs:12:19: 12:21
+          _3 = move _7;                    // scope 0 at $DIR/boxes.rs:12:14: 12:22
+          StorageDead(_7);                 // scope 0 at $DIR/boxes.rs:12:21: 12:22
           _2 = (*_3);                      // scope 0 at $DIR/boxes.rs:12:13: 12:22
           _1 = Add(move _2, const 0_i32);  // scope 0 at $DIR/boxes.rs:12:13: 12:26
           StorageDead(_2);                 // scope 0 at $DIR/boxes.rs:12:25: 12:26
-          drop(_3) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/boxes.rs:12:26: 12:27
+          drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:12:26: 12:27
       }
   
-      bb1: {
+      bb2: {
           StorageDead(_3);                 // scope 0 at $DIR/boxes.rs:12:26: 12:27
           nop;                             // scope 0 at $DIR/boxes.rs:11:11: 13:2
           StorageDead(_1);                 // scope 0 at $DIR/boxes.rs:13:1: 13:2
           return;                          // scope 0 at $DIR/boxes.rs:13:2: 13:2
       }
   
-      bb2 (cleanup): {
+      bb3 (cleanup): {
           resume;                          // scope 0 at $DIR/boxes.rs:11:1: 13:2
       }
   }
index 0c220eb91a4b1b65a4faa98af2d847d4aa7f7e41..137a1de522b83d3723677aedfec2027f8dc3596d 100644 (file)
@@ -4,23 +4,37 @@
   fn main() -> () {
       let mut _0: ();                      // return place in scope 0 at $DIR/inline-into-box-place.rs:7:11: 7:11
       let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
-      let mut _2: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-      let mut _3: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
-+     let mut _4: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+      let mut _2: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _3: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++     let mut _7: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11
       }
-+     scope 2 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
+      scope 2 {
+      }
++     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
 +     }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
-          StorageLive(_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-          _2 = Box(std::vec::Vec<u32>);    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
--         (*_2) = Vec::<u32>::new() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_4);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         _4 = &mut (*_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+                                           // mir::Constant
+                                           // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
+                                           // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageLive(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+-         (*_5) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         _7 = &mut (*_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         ((*_7).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43
 +                                          // ty::Const
 +                                          // + ty: alloc::raw_vec::RawVec<u32>
 +                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 -                                          // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) }
 -     }
 - 
--     bb1: {
+-     bb2: {
 +                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:43
 +                                          // + user_ty: UserType(0)
 +                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
-+         ((*_4).1: usize) = const 0_usize; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageDead(_4);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-          _1 = move _2;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-          StorageDead(_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++         ((*_7).1: usize) = const 0_usize; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
           _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
--         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
-+         drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+-         drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
++         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
       }
   
--     bb2: {
-+     bb1: {
+-     bb3: {
++     bb2: {
           StorageDead(_1);                 // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
           return;                          // scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
       }
   
--     bb3 (cleanup): {
-+     bb2 (cleanup): {
+-     bb4 (cleanup): {
++     bb3 (cleanup): {
           resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
 -     }
 - 
--     bb4 (cleanup): {
--         _3 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_2.1: std::alloc::Global)) -> bb3; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-     bb5 (cleanup): {
+-         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<std::vec::Vec<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
index 7f3a72ee5ad75d158a96c5fb9d700a2be710b624..26327d055746180cda3506513c1435fa719b1661 100644 (file)
@@ -4,23 +4,37 @@
   fn main() -> () {
       let mut _0: ();                      // return place in scope 0 at $DIR/inline-into-box-place.rs:7:11: 7:11
       let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
-      let mut _2: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-      let mut _3: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
-+     let mut _4: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+      let mut _2: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _3: usize;                   // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++     let mut _7: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11
       }
-+     scope 2 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
+      scope 2 {
+      }
++     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
 +     }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
-          StorageLive(_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-          _2 = Box(std::vec::Vec<u32>);    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
--         (*_2) = Vec::<u32>::new() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_4);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         _4 = &mut (*_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:8:29: 8:43
+                                           // mir::Constant
+                                           // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
+                                           // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageLive(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+-         (*_5) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         _7 = &mut (*_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         ((*_7).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43
 +                                          // ty::Const
 +                                          // + ty: alloc::raw_vec::RawVec<u32>
 +                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 -                                          // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) }
 -     }
 - 
--     bb1: {
+-     bb2: {
 +                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:43
 +                                          // + user_ty: UserType(0)
 +                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
-+         ((*_4).1: usize) = const 0_usize; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageDead(_4);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-          _1 = move _2;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
-          StorageDead(_2);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++         ((*_7).1: usize) = const 0_usize; // scope 3 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
           _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
--         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
-+         drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+-         drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
++         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
       }
   
--     bb2: {
-+     bb1: {
+-     bb3: {
++     bb2: {
           StorageDead(_1);                 // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
           return;                          // scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
       }
   
--     bb3 (cleanup): {
-+     bb2 (cleanup): {
+-     bb4 (cleanup): {
++     bb3 (cleanup): {
           resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
 -     }
 - 
--     bb4 (cleanup): {
--         _3 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_2.1: std::alloc::Global)) -> bb3; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-     bb5 (cleanup): {
+-         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<std::vec::Vec<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
index 95efa74289d85b6509f813638dea5abf1ad5d257..dde49c77ae7f5fbdf3cc62fe427eb4ff97c77f62 100644 (file)
 fn test() -> Option<Box<u32>> {
     let mut _0: std::option::Option<std::boxed::Box<u32>>; // return place in scope 0 at $DIR/issue-62289.rs:8:14: 8:30
     let mut _1: std::boxed::Box<u32>;    // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-    let mut _2: std::boxed::Box<u32>;    // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-    let mut _3: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20
-    let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:19
-    let mut _5: isize;                   // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-    let _6: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-    let mut _7: !;                       // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-    let mut _8: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-    let _9: u32;                         // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+    let mut _2: usize;                   // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+    let mut _3: usize;                   // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+    let mut _4: *mut u8;                 // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+    let mut _5: std::boxed::Box<u32>;    // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+    let mut _6: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+    let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:19
+    let mut _8: isize;                   // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+    let _9: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+    let mut _10: !;                      // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+    let mut _11: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+    let _12: u32;                        // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20
     scope 1 {
-        debug residual => _6;            // in scope 1 at $DIR/issue-62289.rs:9:19: 9:20
-        scope 2 {
+    }
+    scope 2 {
+        debug residual => _9;            // in scope 2 at $DIR/issue-62289.rs:9:19: 9:20
+        scope 3 {
         }
     }
-    scope 3 {
-        debug val => _9;                 // in scope 3 at $DIR/issue-62289.rs:9:15: 9:20
-        scope 4 {
+    scope 4 {
+        debug val => _12;                // in scope 4 at $DIR/issue-62289.rs:9:15: 9:20
+        scope 5 {
         }
     }
 
     bb0: {
         StorageLive(_1);                 // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-        StorageLive(_2);                 // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-        _2 = Box(u32);                   // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-        StorageLive(_3);                 // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
-        StorageLive(_4);                 // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
-        _4 = Option::<u32>::None;        // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
-        _3 = <Option<u32> as Try>::branch(move _4) -> [return: bb1, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        _2 = SizeOf(u32);                // scope 1 at $DIR/issue-62289.rs:9:10: 9:21
+        _3 = AlignOf(u32);               // scope 1 at $DIR/issue-62289.rs:9:10: 9:21
+        _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue-62289.rs:9:10: 9:21
                                          // mir::Constant
-                                         // + span: $DIR/issue-62289.rs:9:15: 9:20
-                                         // + literal: Const { ty: fn(std::option::Option<u32>) -> std::ops::ControlFlow<<std::option::Option<u32> as std::ops::Try>::Residual, <std::option::Option<u32> as std::ops::Try>::Output> {<std::option::Option<u32> as std::ops::Try>::branch}, val: Value(Scalar(<ZST>)) }
+                                         // + span: $DIR/issue-62289.rs:9:10: 9:21
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        StorageDead(_4);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-        _5 = discriminant(_3);           // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
-        switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        StorageLive(_5);                 // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+        _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+        StorageLive(_6);                 // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        StorageLive(_7);                 // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
+        _7 = Option::<u32>::None;        // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
+        _6 = <Option<u32> as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+                                         // mir::Constant
+                                         // + span: $DIR/issue-62289.rs:9:15: 9:20
+                                         // + literal: Const { ty: fn(std::option::Option<u32>) -> std::ops::ControlFlow<<std::option::Option<u32> as std::ops::Try>::Residual, <std::option::Option<u32> as std::ops::Try>::Output> {<std::option::Option<u32> as std::ops::Try>::branch}, val: Value(Scalar(<ZST>)) }
     }
 
     bb2: {
-        StorageLive(_9);                 // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
-        _9 = ((_3 as Continue).0: u32);  // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
-        (*_2) = _9;                      // scope 4 at $DIR/issue-62289.rs:9:15: 9:20
-        StorageDead(_9);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-        _1 = move _2;                    // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
-        drop(_2) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+        StorageDead(_7);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+        _8 = discriminant(_6);           // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
     }
 
     bb3: {
-        unreachable;                     // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        StorageLive(_12);                // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
+        (*_5) = _12;                     // scope 5 at $DIR/issue-62289.rs:9:15: 9:20
+        StorageDead(_12);                // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+        _1 = move _5;                    // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
+        drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
     }
 
     bb4: {
-        StorageLive(_6);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-        _6 = ((_3 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-        StorageLive(_8);                 // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
-        _8 = _6;                         // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
-        _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _8) -> [return: bb5, unwind: bb11]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20
-                                         // mir::Constant
-                                         // + span: $DIR/issue-62289.rs:9:19: 9:20
-                                         // + literal: Const { ty: fn(std::option::Option<std::convert::Infallible>) -> std::option::Option<std::boxed::Box<u32>> {<std::option::Option<std::boxed::Box<u32>> as std::ops::FromResidual<std::option::Option<std::convert::Infallible>>>::from_residual}, val: Value(Scalar(<ZST>)) }
+        unreachable;                     // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
     }
 
     bb5: {
-        StorageDead(_8);                 // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
-        StorageDead(_6);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
-        drop(_2) -> bb8;                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+        StorageLive(_9);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+        _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+        StorageLive(_11);                // scope 3 at $DIR/issue-62289.rs:9:19: 9:20
+        _11 = _9;                        // scope 3 at $DIR/issue-62289.rs:9:19: 9:20
+        _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue-62289.rs:9:15: 9:20
+                                         // mir::Constant
+                                         // + span: $DIR/issue-62289.rs:9:19: 9:20
+                                         // + literal: Const { ty: fn(std::option::Option<std::convert::Infallible>) -> std::option::Option<std::boxed::Box<u32>> {<std::option::Option<std::boxed::Box<u32>> as std::ops::FromResidual<std::option::Option<std::convert::Infallible>>>::from_residual}, val: Value(Scalar(<ZST>)) }
     }
 
     bb6: {
-        StorageDead(_2);                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
-        _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:9:5: 9:22
-        drop(_1) -> bb7;                 // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
+        StorageDead(_11);                // scope 3 at $DIR/issue-62289.rs:9:19: 9:20
+        StorageDead(_9);                 // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
+        drop(_5) -> bb9;                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
     }
 
     bb7: {
-        StorageDead(_1);                 // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
-        StorageDead(_3);                 // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
-        goto -> bb9;                     // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
+        StorageDead(_5);                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+        _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:9:5: 9:22
+        drop(_1) -> bb8;                 // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
     }
 
     bb8: {
-        StorageDead(_2);                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
         StorageDead(_1);                 // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
-        StorageDead(_3);                 // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
-        goto -> bb9;                     // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
+        StorageDead(_6);                 // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
+        goto -> bb10;                    // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
     }
 
     bb9: {
-        return;                          // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
+        StorageDead(_5);                 // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+        StorageDead(_1);                 // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
+        StorageDead(_6);                 // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
+        goto -> bb10;                    // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
     }
 
-    bb10 (cleanup): {
-        drop(_1) -> bb12;                // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
+    bb10: {
+        return;                          // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
     }
 
     bb11 (cleanup): {
-        drop(_2) -> bb12;                // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+        drop(_1) -> bb13;                // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
     }
 
     bb12 (cleanup): {
+        drop(_5) -> bb13;                // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
+    }
+
+    bb13 (cleanup): {
         resume;                          // scope 0 at $DIR/issue-62289.rs:8:1: 10:2
     }
 }
index 7f81d9fc482ff91e17445f060855618925bc9e98..d7d2cdf9b0c7577c76c0f828b9af23e2b7db1695 100644 (file)
@@ -4,80 +4,108 @@ fn move_out_by_subslice() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/uniform_array_move_out.rs:10:27: 10:27
     let _1: [std::boxed::Box<i32>; 2];   // in scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10
     let mut _2: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-    let mut _3: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-    let mut _4: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
-    let mut _5: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+    let mut _3: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+    let mut _4: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+    let mut _5: *mut u8;                 // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+    let mut _6: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+    let mut _7: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+    let mut _8: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+    let mut _9: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+    let mut _10: *mut u8;                // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+    let mut _11: std::boxed::Box<i32>;   // in scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
     scope 1 {
         debug a => _1;                   // in scope 1 at $DIR/uniform_array_move_out.rs:11:9: 11:10
-        let _6: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
-        scope 2 {
-            debug _y => _6;              // in scope 2 at $DIR/uniform_array_move_out.rs:12:10: 12:17
+        let _12: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
+        scope 4 {
+            debug _y => _12;             // in scope 4 at $DIR/uniform_array_move_out.rs:12:10: 12:17
         }
     }
+    scope 2 {
+    }
+    scope 3 {
+    }
 
     bb0: {
         StorageLive(_1);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10
         StorageLive(_2);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-        StorageLive(_3);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-        _3 = Box(i32);                   // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-        (*_3) = const 1_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
-        _2 = move _3;                    // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
-        drop(_3) -> [return: bb1, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
+        _3 = SizeOf(i32);                // scope 2 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+        _4 = AlignOf(i32);               // scope 2 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:11:14: 11:19
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        StorageDead(_3);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
-        StorageLive(_4);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
-        StorageLive(_5);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
-        _5 = Box(i32);                   // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
-        (*_5) = const 2_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
-        _4 = move _5;                    // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
-        drop(_5) -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
+        StorageLive(_6);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+        _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+        (*_6) = const 1_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
+        _2 = move _6;                    // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
+        drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
     }
 
     bb2: {
-        StorageDead(_5);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
-        _1 = [move _2, move _4];         // scope 0 at $DIR/uniform_array_move_out.rs:11:13: 11:27
-        drop(_4) -> [return: bb3, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+        StorageDead(_6);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
+        StorageLive(_7);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        _8 = SizeOf(i32);                // scope 3 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        _9 = AlignOf(i32);               // scope 3 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:11:21: 11:26
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb3: {
-        StorageDead(_4);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
-        drop(_2) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+        StorageLive(_11);                // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        (*_11) = const 2_i32;            // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
+        _7 = move _11;                   // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
+        drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
     }
 
     bb4: {
+        StorageDead(_11);                // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
+        _1 = [move _2, move _7];         // scope 0 at $DIR/uniform_array_move_out.rs:11:13: 11:27
+        drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+    }
+
+    bb5: {
+        StorageDead(_7);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+        drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+    }
+
+    bb6: {
         StorageDead(_2);                 // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
         FakeRead(ForLet(None), _1);      // scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10
-        StorageLive(_6);                 // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
-        _6 = move _1[0..2];              // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
+        StorageLive(_12);                // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
+        _12 = move _1[0..2];             // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
         _0 = const ();                   // scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2
-        drop(_6) -> [return: bb5, unwind: bb7]; // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
+        drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
     }
 
-    bb5: {
-        StorageDead(_6);                 // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
-        drop(_1) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
+    bb7: {
+        StorageDead(_12);                // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
+        drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
     }
 
-    bb6: {
+    bb8: {
         StorageDead(_1);                 // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
         return;                          // scope 0 at $DIR/uniform_array_move_out.rs:13:2: 13:2
     }
 
-    bb7 (cleanup): {
-        drop(_1) -> bb10;                // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
+    bb9 (cleanup): {
+        drop(_1) -> bb12;                // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
     }
 
-    bb8 (cleanup): {
-        drop(_4) -> bb9;                 // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+    bb10 (cleanup): {
+        drop(_7) -> bb11;                // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
     }
 
-    bb9 (cleanup): {
-        drop(_2) -> bb10;                // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
+    bb11 (cleanup): {
+        drop(_2) -> bb12;                // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
     }
 
-    bb10 (cleanup): {
+    bb12 (cleanup): {
         resume;                          // scope 0 at $DIR/uniform_array_move_out.rs:10:1: 13:2
     }
 }
index 62ab494c066285935830d66237b7b9bcba83a4bc..18bc1a17c1b50abe24a283d5b59c88e73a2b3c8e 100644 (file)
@@ -4,80 +4,108 @@ fn move_out_from_end() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/uniform_array_move_out.rs:4:24: 4:24
     let _1: [std::boxed::Box<i32>; 2];   // in scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10
     let mut _2: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-    let mut _3: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-    let mut _4: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
-    let mut _5: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+    let mut _3: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+    let mut _4: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+    let mut _5: *mut u8;                 // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+    let mut _6: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+    let mut _7: std::boxed::Box<i32>;    // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+    let mut _8: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+    let mut _9: usize;                   // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+    let mut _10: *mut u8;                // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+    let mut _11: std::boxed::Box<i32>;   // in scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
     scope 1 {
         debug a => _1;                   // in scope 1 at $DIR/uniform_array_move_out.rs:5:9: 5:10
-        let _6: std::boxed::Box<i32>;    // in scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
-        scope 2 {
-            debug _y => _6;              // in scope 2 at $DIR/uniform_array_move_out.rs:6:14: 6:16
+        let _12: std::boxed::Box<i32>;   // in scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
+        scope 4 {
+            debug _y => _12;             // in scope 4 at $DIR/uniform_array_move_out.rs:6:14: 6:16
         }
     }
+    scope 2 {
+    }
+    scope 3 {
+    }
 
     bb0: {
         StorageLive(_1);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10
         StorageLive(_2);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-        StorageLive(_3);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-        _3 = Box(i32);                   // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-        (*_3) = const 1_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
-        _2 = move _3;                    // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
-        drop(_3) -> [return: bb1, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
+        _3 = SizeOf(i32);                // scope 2 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+        _4 = AlignOf(i32);               // scope 2 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+        _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:5:14: 5:19
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        StorageDead(_3);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
-        StorageLive(_4);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
-        StorageLive(_5);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
-        _5 = Box(i32);                   // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
-        (*_5) = const 2_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
-        _4 = move _5;                    // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
-        drop(_5) -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
+        StorageLive(_6);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+        _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+        (*_6) = const 1_i32;             // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
+        _2 = move _6;                    // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
+        drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
     }
 
     bb2: {
-        StorageDead(_5);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
-        _1 = [move _2, move _4];         // scope 0 at $DIR/uniform_array_move_out.rs:5:13: 5:27
-        drop(_4) -> [return: bb3, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+        StorageDead(_6);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
+        StorageLive(_7);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        _8 = SizeOf(i32);                // scope 3 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        _9 = AlignOf(i32);               // scope 3 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:5:21: 5:26
+                                         // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
     }
 
     bb3: {
-        StorageDead(_4);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
-        drop(_2) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+        StorageLive(_11);                // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        (*_11) = const 2_i32;            // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
+        _7 = move _11;                   // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
+        drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
     }
 
     bb4: {
+        StorageDead(_11);                // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
+        _1 = [move _2, move _7];         // scope 0 at $DIR/uniform_array_move_out.rs:5:13: 5:27
+        drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+    }
+
+    bb5: {
+        StorageDead(_7);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+        drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+    }
+
+    bb6: {
         StorageDead(_2);                 // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
         FakeRead(ForLet(None), _1);      // scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10
-        StorageLive(_6);                 // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
-        _6 = move _1[1 of 2];            // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
+        StorageLive(_12);                // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
+        _12 = move _1[1 of 2];           // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
         _0 = const ();                   // scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2
-        drop(_6) -> [return: bb5, unwind: bb7]; // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
+        drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
     }
 
-    bb5: {
-        StorageDead(_6);                 // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
-        drop(_1) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
+    bb7: {
+        StorageDead(_12);                // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
+        drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
     }
 
-    bb6: {
+    bb8: {
         StorageDead(_1);                 // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
         return;                          // scope 0 at $DIR/uniform_array_move_out.rs:7:2: 7:2
     }
 
-    bb7 (cleanup): {
-        drop(_1) -> bb10;                // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
+    bb9 (cleanup): {
+        drop(_1) -> bb12;                // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
     }
 
-    bb8 (cleanup): {
-        drop(_4) -> bb9;                 // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+    bb10 (cleanup): {
+        drop(_7) -> bb11;                // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
     }
 
-    bb9 (cleanup): {
-        drop(_2) -> bb10;                // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
+    bb11 (cleanup): {
+        drop(_2) -> bb12;                // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
     }
 
-    bb10 (cleanup): {
+    bb12 (cleanup): {
         resume;                          // scope 0 at $DIR/uniform_array_move_out.rs:4:1: 7:2
     }
 }
index 4eccba06b134ffbaf011ac1d52ff8b89cf3fc946..f4be3c1c63a84e5d8fda7b09ff7cf076ed3bebe6 100644 (file)
@@ -10,11 +10,9 @@ extern crate std;
 
 fn main() {
     {
-        ::std::io::_print(match match () { () => [], } {
-                              ref args => unsafe {
-                                  ::core::fmt::Arguments::new_v1(&["rust\n"],
-                                                                 args)
-                              }
-                          });
+        ::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"],
+                                                         &match () {
+                                                              () => [],
+                                                          }));
     };
 }
index a21ea520121e38f6c2c845328086e5840bfe79be..199aee05622beed636c3966d6a00f091fae86cdd 100644 (file)
@@ -32,39 +32,29 @@ pub fn bar() ({
                   ({
                        let res =
                            ((::alloc::fmt::format as
-                                for<'r> fn(Arguments<'r>) -> String {format})((match (match (()
-                                                                                                as
-                                                                                                ())
-                                                                                          {
-                                                                                          ()
-                                                                                          =>
-                                                                                          ([]
-                                                                                              as
-                                                                                              [ArgumentV1; 0]),
-                                                                                      }
-                                                                                         as
-                                                                                         [ArgumentV1; 0])
-                                                                                   {
-                                                                                   ref args
-                                                                                   =>
-                                                                                   unsafe
-                                                                                   {
-                                                                                       ((::core::fmt::Arguments::new_v1
-                                                                                            as
-                                                                                            unsafe fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test"
-                                                                                                                                                                                as
-                                                                                                                                                                                &str)]
-                                                                                                                                                                              as
-                                                                                                                                                                              [&str; 1])
-                                                                                                                                                                            as
-                                                                                                                                                                            &[&str; 1]),
-                                                                                                                                                                        (args
-                                                                                                                                                                            as
-                                                                                                                                                                            &[ArgumentV1; 0]))
-                                                                                           as
-                                                                                           Arguments)
-                                                                                   }
-                                                                               }
+                                for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_v1
+                                                                                   as
+                                                                                   fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test"
+                                                                                                                                                                as
+                                                                                                                                                                &str)]
+                                                                                                                                                              as
+                                                                                                                                                              [&str; 1])
+                                                                                                                                                            as
+                                                                                                                                                            &[&str; 1]),
+                                                                                                                                                        (&(match (()
+                                                                                                                                                                     as
+                                                                                                                                                                     ())
+                                                                                                                                                               {
+                                                                                                                                                               ()
+                                                                                                                                                               =>
+                                                                                                                                                               ([]
+                                                                                                                                                                   as
+                                                                                                                                                                   [ArgumentV1; 0]),
+                                                                                                                                                           }
+                                                                                                                                                              as
+                                                                                                                                                              [ArgumentV1; 0])
+                                                                                                                                                            as
+                                                                                                                                                            &[ArgumentV1; 0]))
                                                                                   as
                                                                                   Arguments))
                                as String);
index b35f3f54de9044671f3d7ffd2e429af5b421dde3..f24f7c69404731214ef8cfad027233d6f6727c01 100644 (file)
    24|      1|    println!("{:?}", Foo(1));
    25|      1|
    26|      1|    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
-                                             ^0       ^0        ^0                      ^0
+                                             ^0                 ^0                      ^0
    27|      1|    assert_ne!(
    28|       |        Foo(0)
    29|       |        ,
    30|       |        Foo(5)
    31|       |        ,
    32|      0|        "{}"
-   33|       |        ,
-   34|       |        if
+   33|      0|        ,
+   34|      0|        if
    35|      0|        is_true
    36|       |        {
    37|      0|            "true message"
index 120b6e9747f4aef1f8f1da144f5e6365f38b6dd0..4ba296ee04a1a5218acb1117d72c1ee4740eca42 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:primitive-doc.rs
 // compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
-// ignore-windows
+// only-linux
 
 #![feature(no_core)]
 #![no_core]
diff --git a/src/test/rustdoc/hidden-trait-methods-with-document-hidden-items.rs b/src/test/rustdoc/hidden-trait-methods-with-document-hidden-items.rs
new file mode 100644 (file)
index 0000000..95b3e9b
--- /dev/null
@@ -0,0 +1,31 @@
+// compile-flags: -Z unstable-options --document-hidden-items
+
+// test for trait methods with `doc(hidden)` with `--document-hidden-items` passed.
+#![crate_name = "foo"]
+
+// @has foo/trait.Trait.html
+// @has - '//*[@id="associatedtype.Foo"]' 'type Foo'
+// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
+// @has - '//*[@id="tymethod.f"]' 'fn f()'
+// @has - '//*[@id="tymethod.g"]' 'fn g()'
+pub trait Trait {
+    #[doc(hidden)]
+    type Foo;
+    type Bar;
+    #[doc(hidden)]
+    fn f();
+    fn g();
+}
+
+// @has foo/struct.S.html
+// @has - '//*[@id="associatedtype.Foo"]' 'type Foo'
+// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
+// @has - '//*[@id="method.f"]' 'fn f()'
+// @has - '//*[@id="method.g"]' 'fn g()'
+pub struct S;
+impl Trait for S {
+    type Foo = ();
+    type Bar = ();
+    fn f() {}
+    fn g() {}
+}
diff --git a/src/test/rustdoc/hidden-trait-methods.rs b/src/test/rustdoc/hidden-trait-methods.rs
new file mode 100644 (file)
index 0000000..e924ba7
--- /dev/null
@@ -0,0 +1,29 @@
+// test for trait methods with `doc(hidden)`.
+#![crate_name = "foo"]
+
+// @has foo/trait.Trait.html
+// @!has - '//*[@id="associatedtype.Foo"]' 'type Foo'
+// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
+// @!has - '//*[@id="tymethod.f"]' 'fn f()'
+// @has - '//*[@id="tymethod.g"]' 'fn g()'
+pub trait Trait {
+    #[doc(hidden)]
+    type Foo;
+    type Bar;
+    #[doc(hidden)]
+    fn f();
+    fn g();
+}
+
+// @has foo/struct.S.html
+// @!has - '//*[@id="associatedtype.Foo"]' 'type Foo'
+// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
+// @!has - '//*[@id="method.f"]' 'fn f()'
+// @has - '//*[@id="method.g"]' 'fn g()'
+pub struct S;
+impl Trait for S {
+    type Foo = ();
+    type Bar = ();
+    fn f() {}
+    fn g() {}
+}
index 5a92a28556eded64fb62281464527a128d3027af..9d869984bbd7ce7e1d6333df122ae3fcdd9c267e 100644 (file)
@@ -1,7 +1,7 @@
 // aux-build:my-core.rs
 // build-aux-docs
 // ignore-cross-compile
-// ignore-windows
+// only-linux
 
 #![deny(broken_intra_doc_links)]
 #![feature(no_core, lang_items)]
index 460785ed979de3d6b24d40b1a7a360bbbd35155f..7576c1326b8e494c8902d21888a85976639d9d82 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-test (fails spuriously, see issue #89228)
+
 // FIXME: If two macros in the same module have the same name
 // (yes, that's a thing), rustdoc lists both of them on the index page,
 // but only documents the first one on the page for the macro.
index 0b68d5e04f7a208b262f52e7819f33e38fe548e7..8051c58898e499241a41ead3775deea95e4b85e4 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(box_syntax, plugin, rustc_private)]
+#![feature(plugin, rustc_private)]
 #![crate_type = "dylib"]
 
 extern crate rustc_ast_pretty;
@@ -21,7 +21,7 @@
 #[no_mangle]
 fn __rustc_plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
-    reg.lint_store.register_late_pass(|| box MissingAllowedAttrPass);
+    reg.lint_store.register_late_pass(|| Box::new(MissingAllowedAttrPass));
 }
 
 declare_lint! {
index 0015a826126ff5776117f4511e1c5c12a00dcd70..fc57c14ec32b15e5be62f08720917d25cb502e03 100644 (file)
@@ -1,7 +1,6 @@
 // force-host
 
 #![feature(rustc_private)]
-#![feature(box_syntax)]
 
 extern crate rustc_driver;
 extern crate rustc_hir;
@@ -73,7 +72,7 @@ fn __rustc_plugin_registrar(reg: &mut Registry) {
         &CRATE_NOT_GREY,
         &CRATE_NOT_GREEN,
     ]);
-    reg.lint_store.register_late_pass(|| box PassOkay);
-    reg.lint_store.register_late_pass(|| box PassRedBlue);
-    reg.lint_store.register_late_pass(|| box PassGreyGreen);
+    reg.lint_store.register_late_pass(|| Box::new(PassOkay));
+    reg.lint_store.register_late_pass(|| Box::new(PassRedBlue));
+    reg.lint_store.register_late_pass(|| Box::new(PassGreyGreen));
 }
index 87c90b53648c79901be67c28a50950128554e5c4..78c6c7ed887a903a49215fa90101086854e4879d 100644 (file)
@@ -1,7 +1,6 @@
 // force-host
 
 #![feature(rustc_private)]
-#![feature(box_syntax)]
 
 extern crate rustc_driver;
 extern crate rustc_hir;
@@ -41,5 +40,5 @@ fn check_crate(&mut self, cx: &LateContext, krate: &rustc_hir::Crate) {
 #[no_mangle]
 fn __rustc_plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
-    reg.lint_store.register_late_pass(|| box Pass);
+    reg.lint_store.register_late_pass(|| Box::new(Pass));
 }
index f6ae560411b8e8f4cba0b29c39e8ba93444ffe97..253855fd2edd48edc3b14d7f5021f59f1fd3de6a 100644 (file)
@@ -1,6 +1,6 @@
 // force-host
 
-#![feature(box_syntax, rustc_private)]
+#![feature(rustc_private)]
 
 // Load rustc as a plugin to get macros.
 extern crate rustc_driver;
@@ -36,7 +36,7 @@ fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) {
 #[no_mangle]
 fn __rustc_plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
-    reg.lint_store.register_late_pass(|| box Pass);
+    reg.lint_store.register_late_pass(|| Box::new(Pass));
     reg.lint_store.register_group(
         true,
         "lint_me",
index 32326bc8a5e5083ede7cefb6dcab661529106857..42368ec36a028d03103b816740fa031e990740bb 100644 (file)
@@ -1,6 +1,6 @@
 // force-host
 
-#![feature(box_syntax, rustc_private)]
+#![feature(rustc_private)]
 
 extern crate rustc_ast;
 
@@ -31,5 +31,5 @@ fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
 #[no_mangle]
 fn __rustc_plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&TEST_LINT]);
-    reg.lint_store.register_early_pass(|| box Pass);
+    reg.lint_store.register_early_pass(|| Box::new(Pass));
 }
index 42c1c851de8231105e1f7dd3876bbe11aeae6ca4..81feddf571323341dd4c9d224f7d20a865eaa7b4 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(box_syntax, rustc_private)]
+#![feature(rustc_private)]
 
 extern crate rustc_ast;
 
@@ -46,7 +46,7 @@ fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
 #[no_mangle]
 fn __rustc_plugin_registrar(reg: &mut Registry) {
     reg.lint_store.register_lints(&[&TEST_RUSTC_TOOL_LINT, &TEST_LINT, &TEST_GROUP]);
-    reg.lint_store.register_early_pass(|| box Pass);
+    reg.lint_store.register_early_pass(|| Box::new(Pass));
     reg.lint_store.register_group(
         true,
         "clippy::group",
index d0eedf23cafe9661923f7ae9478ba2a5b6a3205a..e83dfe80463d882b715b525ea7f8f0ec97b15802 100644 (file)
@@ -1,6 +1,6 @@
 // force-host
 
-#![feature(box_syntax, rustc_private)]
+#![feature(rustc_private)]
 
 extern crate rustc_middle;
 extern crate rustc_driver;
@@ -20,5 +20,5 @@ fn drop(&mut self) {}
 #[no_mangle]
 fn __rustc_plugin_registrar(_: &mut Registry) {
     thread_local!(static FOO: RefCell<Option<Box<Any+Send>>> = RefCell::new(None));
-    FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box<Any+Send>));
+    FOO.with(|s| *s.borrow_mut() = Some(Box::new(Foo { foo: 10 }) as Box<Any+Send>));
 }
index 119fa3d6fa8efcf9ad60ab93805879dce4061812..fab2031d952356a5b136cc8039b25e823c4c076a 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
 
 #![allow(unused_imports)]
-#![feature(box_syntax)]
 #![feature(rustc_private)]
 
 extern crate rustc_macros;
index adbd05ed8c1757593995a802f856518ad7ae3d6e..eb503dcf3b63bb2083a5bbd1f7f80a640f8c12f6 100644 (file)
@@ -3,8 +3,6 @@
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
 
-#![feature(box_syntax)]
-
 struct pair<A,B> {
     a: A, b: B
 }
@@ -25,10 +23,10 @@ fn f(&self) -> (A, u16) {
 }
 
 fn f<A:Clone + 'static>(a: A, b: u16) -> Box<dyn Invokable<A>+'static> {
-    box Invoker {
+    Box::new(Invoker {
         a: a,
         b: b,
-    } as Box<dyn Invokable<A>+'static>
+    }) as Box<dyn Invokable<A>+'static>
 }
 
 pub fn main() {
index e741201652ba0d9ff7f82884a078d88e2876778e..c58ddbc4239460029f7128105d107bf31274cec0 100644 (file)
@@ -1,11 +1,9 @@
 // run-pass
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    // Tests for indexing into box/& [T; n]
+    // Tests for indexing into Box<[T; n]>/& [T; n]
     let x: [isize; 3] = [1, 2, 3];
-    let mut x: Box<[isize; 3]> = box x;
+    let mut x: Box<[isize; 3]> = x.into();
     assert_eq!(x[0], 1);
     assert_eq!(x[1], 2);
     assert_eq!(x[2], 3);
index dd8f402f3f6a59570b1808ee361ffd4a3bb0f98e..e2055f551acc4b3d660b4078ce31dd4544b7482c 100644 (file)
@@ -2,6 +2,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
-pub fn main() { let _quux: Box<Vec<usize>> = box Vec::new(); }
+pub fn main() {
+    let _quux: Box<Vec<usize>> = Box::new(Vec::new());
+}
diff --git a/src/test/ui/asm/aarch64/bad-options.rs b/src/test/ui/asm/aarch64/bad-options.rs
new file mode 100644 (file)
index 0000000..8775eba
--- /dev/null
@@ -0,0 +1,39 @@
+// only-aarch64
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    let mut foo = 0;
+    unsafe {
+        asm!("", options(nomem, readonly));
+        //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
+        asm!("", options(pure, nomem, noreturn));
+        //~^ ERROR the `pure` and `noreturn` options are mutually exclusive
+        //~^^ ERROR asm with the `pure` option must have at least one output
+        asm!("{}", in(reg) foo, options(pure, nomem));
+        //~^ ERROR asm with the `pure` option must have at least one output
+        asm!("{}", out(reg) foo, options(noreturn));
+        //~^ ERROR asm outputs are not allowed with the `noreturn` option
+    }
+
+    unsafe {
+        asm!("", clobber_abi("foo"));
+        //~^ ERROR invalid ABI for `clobber_abi`
+        asm!("{}", out(reg) foo, clobber_abi("C"));
+        //~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs
+        asm!("", out("x0") foo, clobber_abi("C"));
+    }
+}
+
+global_asm!("", options(nomem));
+//~^ ERROR expected one of
+global_asm!("", options(readonly));
+//~^ ERROR expected one of
+global_asm!("", options(noreturn));
+//~^ ERROR expected one of
+global_asm!("", options(pure));
+//~^ ERROR expected one of
+global_asm!("", options(nostack));
+//~^ ERROR expected one of
+global_asm!("", options(preserves_flags));
+//~^ ERROR expected one of
diff --git a/src/test/ui/asm/aarch64/bad-options.stderr b/src/test/ui/asm/aarch64/bad-options.stderr
new file mode 100644 (file)
index 0000000..21bcc4a
--- /dev/null
@@ -0,0 +1,84 @@
+error: the `nomem` and `readonly` options are mutually exclusive
+  --> $DIR/bad-options.rs:8:18
+   |
+LL |         asm!("", options(nomem, readonly));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `pure` and `noreturn` options are mutually exclusive
+  --> $DIR/bad-options.rs:10:18
+   |
+LL |         asm!("", options(pure, nomem, noreturn));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: asm with the `pure` option must have at least one output
+  --> $DIR/bad-options.rs:10:18
+   |
+LL |         asm!("", options(pure, nomem, noreturn));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: asm with the `pure` option must have at least one output
+  --> $DIR/bad-options.rs:13:33
+   |
+LL |         asm!("{}", in(reg) foo, options(pure, nomem));
+   |                                 ^^^^^^^^^^^^^^^^^^^^
+
+error: asm outputs are not allowed with the `noreturn` option
+  --> $DIR/bad-options.rs:15:20
+   |
+LL |         asm!("{}", out(reg) foo, options(noreturn));
+   |                    ^^^^^^^^^^^^
+
+error: asm with `clobber_abi` must specify explicit registers for outputs
+  --> $DIR/bad-options.rs:22:20
+   |
+LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
+   |                    ^^^^^^^^^^^^  ---------------- clobber_abi
+   |                    |
+   |                    generic outputs
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/bad-options.rs:28:25
+   |
+LL | global_asm!("", options(nomem));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
+  --> $DIR/bad-options.rs:30:25
+   |
+LL | global_asm!("", options(readonly));
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
+  --> $DIR/bad-options.rs:32:25
+   |
+LL | global_asm!("", options(noreturn));
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
+  --> $DIR/bad-options.rs:34:25
+   |
+LL | global_asm!("", options(pure));
+   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
+  --> $DIR/bad-options.rs:36:25
+   |
+LL | global_asm!("", options(nostack));
+   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
+  --> $DIR/bad-options.rs:38:25
+   |
+LL | global_asm!("", options(preserves_flags));
+   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: invalid ABI for `clobber_abi`
+  --> $DIR/bad-options.rs:20:18
+   |
+LL |         asm!("", clobber_abi("foo"));
+   |                  ^^^^^^^^^^^^^^^^^^
+   |
+   = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/ui/asm/aarch64/bad-reg.rs b/src/test/ui/asm/aarch64/bad-reg.rs
new file mode 100644 (file)
index 0000000..22d0499
--- /dev/null
@@ -0,0 +1,59 @@
+// only-aarch64
+// compile-flags: -C target-feature=+fp
+
+#![feature(asm)]
+
+fn main() {
+    let mut foo = 0;
+    let mut bar = 0;
+    unsafe {
+        // Bad register/register class
+
+        asm!("{}", in(foo) foo);
+        //~^ ERROR invalid register class `foo`: unknown register class
+        asm!("", in("foo") foo);
+        //~^ ERROR invalid register `foo`: unknown register
+        asm!("{:z}", in(reg) foo);
+        //~^ ERROR invalid asm template modifier for this register class
+        asm!("{:r}", in(vreg) foo);
+        //~^ ERROR invalid asm template modifier for this register class
+        asm!("{:r}", in(vreg_low16) foo);
+        //~^ ERROR invalid asm template modifier for this register class
+        asm!("{:a}", const 0);
+        //~^ ERROR asm template modifiers are not allowed for `const` arguments
+        asm!("{:a}", sym main);
+        //~^ ERROR asm template modifiers are not allowed for `sym` arguments
+        asm!("", in("x29") foo);
+        //~^ ERROR invalid register `x29`: the frame pointer cannot be used as an operand
+        asm!("", in("sp") foo);
+        //~^ ERROR invalid register `sp`: the stack pointer cannot be used as an operand
+        asm!("", in("xzr") foo);
+        //~^ ERROR invalid register `xzr`: the zero register cannot be used as an operand
+        asm!("", in("x18") foo);
+        //~^ ERROR invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
+        asm!("", in("x19") foo);
+        //~^ ERROR invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
+
+        asm!("", in("p0") foo);
+        //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
+        asm!("", out("p0") _);
+        asm!("{}", in(preg) foo);
+        //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
+        asm!("{}", out(preg) _);
+        //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
+
+        // Explicit register conflicts
+        // (except in/lateout which don't conflict)
+
+        asm!("", in("x0") foo, in("w0") bar);
+        //~^ ERROR register `x0` conflicts with register `x0`
+        asm!("", in("x0") foo, out("x0") bar);
+        //~^ ERROR register `x0` conflicts with register `x0`
+        asm!("", in("w0") foo, lateout("w0") bar);
+        asm!("", in("v0") foo, in("q0") bar);
+        //~^ ERROR register `v0` conflicts with register `v0`
+        asm!("", in("v0") foo, out("q0") bar);
+        //~^ ERROR register `v0` conflicts with register `v0`
+        asm!("", in("v0") foo, lateout("q0") bar);
+    }
+}
diff --git a/src/test/ui/asm/aarch64/bad-reg.stderr b/src/test/ui/asm/aarch64/bad-reg.stderr
new file mode 100644 (file)
index 0000000..091e607
--- /dev/null
@@ -0,0 +1,152 @@
+error: invalid register class `foo`: unknown register class
+  --> $DIR/bad-reg.rs:12:20
+   |
+LL |         asm!("{}", in(foo) foo);
+   |                    ^^^^^^^^^^^
+
+error: invalid register `foo`: unknown register
+  --> $DIR/bad-reg.rs:14:18
+   |
+LL |         asm!("", in("foo") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid asm template modifier for this register class
+  --> $DIR/bad-reg.rs:16:15
+   |
+LL |         asm!("{:z}", in(reg) foo);
+   |               ^^^^   ----------- argument
+   |               |
+   |               template modifier
+   |
+   = note: the `reg` register class supports the following template modifiers: `w`, `x`
+
+error: invalid asm template modifier for this register class
+  --> $DIR/bad-reg.rs:18:15
+   |
+LL |         asm!("{:r}", in(vreg) foo);
+   |               ^^^^   ------------ argument
+   |               |
+   |               template modifier
+   |
+   = note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
+
+error: invalid asm template modifier for this register class
+  --> $DIR/bad-reg.rs:20:15
+   |
+LL |         asm!("{:r}", in(vreg_low16) foo);
+   |               ^^^^   ------------------ argument
+   |               |
+   |               template modifier
+   |
+   = note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
+
+error: asm template modifiers are not allowed for `const` arguments
+  --> $DIR/bad-reg.rs:22:15
+   |
+LL |         asm!("{:a}", const 0);
+   |               ^^^^   ------- argument
+   |               |
+   |               template modifier
+
+error: asm template modifiers are not allowed for `sym` arguments
+  --> $DIR/bad-reg.rs:24:15
+   |
+LL |         asm!("{:a}", sym main);
+   |               ^^^^   -------- argument
+   |               |
+   |               template modifier
+
+error: invalid register `x29`: the frame pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:26:18
+   |
+LL |         asm!("", in("x29") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:28:18
+   |
+LL |         asm!("", in("sp") foo);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `xzr`: the zero register cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:30:18
+   |
+LL |         asm!("", in("xzr") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:32:18
+   |
+LL |         asm!("", in("x18") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:34:18
+   |
+LL |         asm!("", in("x19") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: register class `preg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:37:18
+   |
+LL |         asm!("", in("p0") foo);
+   |                  ^^^^^^^^^^^^
+
+error: register class `preg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:40:20
+   |
+LL |         asm!("{}", in(preg) foo);
+   |                    ^^^^^^^^^^^^
+
+error: register class `preg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:42:20
+   |
+LL |         asm!("{}", out(preg) _);
+   |                    ^^^^^^^^^^^
+
+error: register `x0` conflicts with register `x0`
+  --> $DIR/bad-reg.rs:48:32
+   |
+LL |         asm!("", in("x0") foo, in("w0") bar);
+   |                  ------------  ^^^^^^^^^^^^ register `x0`
+   |                  |
+   |                  register `x0`
+
+error: register `x0` conflicts with register `x0`
+  --> $DIR/bad-reg.rs:50:32
+   |
+LL |         asm!("", in("x0") foo, out("x0") bar);
+   |                  ------------  ^^^^^^^^^^^^^ register `x0`
+   |                  |
+   |                  register `x0`
+   |
+help: use `lateout` instead of `out` to avoid conflict
+  --> $DIR/bad-reg.rs:50:18
+   |
+LL |         asm!("", in("x0") foo, out("x0") bar);
+   |                  ^^^^^^^^^^^^
+
+error: register `v0` conflicts with register `v0`
+  --> $DIR/bad-reg.rs:53:32
+   |
+LL |         asm!("", in("v0") foo, in("q0") bar);
+   |                  ------------  ^^^^^^^^^^^^ register `v0`
+   |                  |
+   |                  register `v0`
+
+error: register `v0` conflicts with register `v0`
+  --> $DIR/bad-reg.rs:55:32
+   |
+LL |         asm!("", in("v0") foo, out("q0") bar);
+   |                  ------------  ^^^^^^^^^^^^^ register `v0`
+   |                  |
+   |                  register `v0`
+   |
+help: use `lateout` instead of `out` to avoid conflict
+  --> $DIR/bad-reg.rs:55:18
+   |
+LL |         asm!("", in("v0") foo, out("q0") bar);
+   |                  ^^^^^^^^^^^^
+
+error: aborting due to 19 previous errors
+
diff --git a/src/test/ui/asm/aarch64/const.rs b/src/test/ui/asm/aarch64/const.rs
new file mode 100644 (file)
index 0000000..906dcb0
--- /dev/null
@@ -0,0 +1,42 @@
+// min-llvm-version: 10.0.1
+// only-aarch64
+// run-pass
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(asm, global_asm)]
+
+fn const_generic<const X: usize>() -> usize {
+    unsafe {
+        let a: usize;
+        asm!("mov {}, {}", out(reg) a, const X);
+        a
+    }
+}
+
+const fn constfn(x: usize) -> usize {
+    x
+}
+
+fn main() {
+    unsafe {
+        let a: usize;
+        asm!("mov {}, {}", out(reg) a, const 5);
+        assert_eq!(a, 5);
+
+        let b: usize;
+        asm!("mov {}, {}", out(reg) b, const constfn(5));
+        assert_eq!(b, 5);
+
+        let c: usize;
+        asm!("mov {}, {}", out(reg) c, const constfn(5) + constfn(5));
+        assert_eq!(c, 10);
+    }
+
+    let d = const_generic::<5>();
+    assert_eq!(d, 5);
+}
+
+global_asm!("mov x0, {}", const 5);
+global_asm!("mov x0, {}", const constfn(5));
+global_asm!("mov x0, {}", const constfn(5) + constfn(5));
diff --git a/src/test/ui/asm/aarch64/duplicate-options.fixed b/src/test/ui/asm/aarch64/duplicate-options.fixed
new file mode 100644 (file)
index 0000000..d95c646
--- /dev/null
@@ -0,0 +1,26 @@
+// only-aarch64
+// run-rustfix
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    unsafe {
+        asm!("", options(nomem, ));
+        //~^ ERROR the `nomem` option was already provided
+        asm!("", options(preserves_flags, ));
+        //~^ ERROR the `preserves_flags` option was already provided
+        asm!("", options(nostack, preserves_flags), options());
+        //~^ ERROR the `nostack` option was already provided
+        asm!("", options(nostack, ), options(), options());
+        //~^ ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        asm!(
+            "",
+            options(nomem, noreturn),
+            options(preserves_flags, ), //~ ERROR the `noreturn` option was already provided
+            options( nostack), //~ ERROR the `nomem` option was already provided
+            options(), //~ ERROR the `noreturn` option was already provided
+        );
+    }
+}
diff --git a/src/test/ui/asm/aarch64/duplicate-options.rs b/src/test/ui/asm/aarch64/duplicate-options.rs
new file mode 100644 (file)
index 0000000..eec3564
--- /dev/null
@@ -0,0 +1,26 @@
+// only-aarch64
+// run-rustfix
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    unsafe {
+        asm!("", options(nomem, nomem));
+        //~^ ERROR the `nomem` option was already provided
+        asm!("", options(preserves_flags, preserves_flags));
+        //~^ ERROR the `preserves_flags` option was already provided
+        asm!("", options(nostack, preserves_flags), options(nostack));
+        //~^ ERROR the `nostack` option was already provided
+        asm!("", options(nostack, nostack), options(nostack), options(nostack));
+        //~^ ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        asm!(
+            "",
+            options(nomem, noreturn),
+            options(preserves_flags, noreturn), //~ ERROR the `noreturn` option was already provided
+            options(nomem, nostack), //~ ERROR the `nomem` option was already provided
+            options(noreturn), //~ ERROR the `noreturn` option was already provided
+        );
+    }
+}
diff --git a/src/test/ui/asm/aarch64/duplicate-options.stderr b/src/test/ui/asm/aarch64/duplicate-options.stderr
new file mode 100644 (file)
index 0000000..5063b0c
--- /dev/null
@@ -0,0 +1,56 @@
+error: the `nomem` option was already provided
+  --> $DIR/duplicate-options.rs:8:33
+   |
+LL |         asm!("", options(nomem, nomem));
+   |                                 ^^^^^ this option was already provided
+
+error: the `preserves_flags` option was already provided
+  --> $DIR/duplicate-options.rs:10:43
+   |
+LL |         asm!("", options(preserves_flags, preserves_flags));
+   |                                           ^^^^^^^^^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:12:61
+   |
+LL |         asm!("", options(nostack, preserves_flags), options(nostack));
+   |                                                             ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:35
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                   ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:53
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                                     ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:71
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                                                       ^^^^^^^ this option was already provided
+
+error: the `noreturn` option was already provided
+  --> $DIR/duplicate-options.rs:21:38
+   |
+LL |             options(preserves_flags, noreturn),
+   |                                      ^^^^^^^^ this option was already provided
+
+error: the `nomem` option was already provided
+  --> $DIR/duplicate-options.rs:22:21
+   |
+LL |             options(nomem, nostack),
+   |                     ^^^^^ this option was already provided
+
+error: the `noreturn` option was already provided
+  --> $DIR/duplicate-options.rs:23:21
+   |
+LL |             options(noreturn),
+   |                     ^^^^^^^^ this option was already provided
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/asm/aarch64/interpolated-idents.rs b/src/test/ui/asm/aarch64/interpolated-idents.rs
new file mode 100644 (file)
index 0000000..1cdf096
--- /dev/null
@@ -0,0 +1,24 @@
+// only-aarch64
+
+#![feature(asm)]
+
+macro_rules! m {
+    ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
+     $pure:ident $nomem:ident $readonly:ident $preserves_flags:ident
+     $noreturn:ident $nostack:ident $options:ident) => {
+        unsafe {
+            asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+            //~^ ERROR asm outputs are not allowed with the `noreturn` option
+            const x, sym x,
+            $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack));
+            //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
+            //~| ERROR the `pure` and `noreturn` options are mutually exclusive
+        }
+    };
+}
+
+fn main() {
+    m!(in out lateout inout inlateout const sym
+       pure nomem readonly preserves_flags
+       noreturn nostack options);
+}
diff --git a/src/test/ui/asm/aarch64/interpolated-idents.stderr b/src/test/ui/asm/aarch64/interpolated-idents.stderr
new file mode 100644 (file)
index 0000000..d1ab13a
--- /dev/null
@@ -0,0 +1,51 @@
+error: the `nomem` and `readonly` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack options);
+   | |_________________________________- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: the `pure` and `noreturn` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack options);
+   | |_________________________________- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm outputs are not allowed with the `noreturn` option
+  --> $DIR/interpolated-idents.rs:10:32
+   |
+LL |               asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+   |                                  ^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^^^^^^^^
+...
+LL |       m!(in out lateout inout inlateout const sym
+   |  _____-
+   | |_____|
+   | |_____|
+   | |_____|
+   | |
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack options);
+   | |                                 -
+   | |_________________________________|
+   | |_________________________________in this macro invocation
+   | |_________________________________in this macro invocation
+   | |_________________________________in this macro invocation
+   |                                   in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs
new file mode 100644 (file)
index 0000000..faa5e37
--- /dev/null
@@ -0,0 +1,135 @@
+// only-aarch64
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    let mut foo = 0;
+    let mut bar = 0;
+    unsafe {
+        asm!();
+        //~^ ERROR requires at least a template string argument
+        asm!(foo);
+        //~^ ERROR asm template must be a string literal
+        asm!("{}" foo);
+        //~^ ERROR expected token: `,`
+        asm!("{}", foo);
+        //~^ ERROR expected operand, clobber_abi, options, or additional template string
+        asm!("{}", in foo);
+        //~^ ERROR expected `(`, found `foo`
+        asm!("{}", in(reg foo));
+        //~^ ERROR expected `)`, found `foo`
+        asm!("{}", in(reg));
+        //~^ ERROR expected expression, found end of macro arguments
+        asm!("{}", inout(=) foo => bar);
+        //~^ ERROR expected register class or explicit register
+        asm!("{}", inout(reg) foo =>);
+        //~^ ERROR expected expression, found end of macro arguments
+        asm!("{}", in(reg) foo => bar);
+        //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
+        asm!("{}", sym foo + bar);
+        //~^ ERROR argument to `sym` must be a path expression
+        asm!("", options(foo));
+        //~^ ERROR expected one of
+        asm!("", options(nomem foo));
+        //~^ ERROR expected one of
+        asm!("", options(nomem, foo));
+        //~^ ERROR expected one of
+        asm!("{}", options(), const foo);
+        //~^ ERROR arguments are not allowed after options
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", clobber_abi(foo));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi("C" foo));
+        //~^ ERROR expected `)`, found `foo`
+        asm!("", clobber_abi("C", foo));
+        //~^ ERROR expected `)`, found `,`
+        asm!("{}", clobber_abi("C"), const foo);
+        //~^ ERROR arguments are not allowed after clobber_abi
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", options(), clobber_abi("C"));
+        //~^ ERROR clobber_abi is not allowed after options
+        asm!("{}", options(), clobber_abi("C"), const foo);
+        //~^ ERROR clobber_abi is not allowed after options
+        asm!("", clobber_abi("C"), clobber_abi("C"));
+        //~^ ERROR clobber_abi specified multiple times
+        asm!("{a}", a = const foo, a = const bar);
+        //~^ ERROR duplicate argument named `a`
+        //~^^ ERROR argument never used
+        //~^^^ ERROR attempt to use a non-constant value in a constant
+        //~^^^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", a = in("x0") foo);
+        //~^ ERROR explicit register arguments cannot have names
+        asm!("{a}", in("x0") foo, a = const bar);
+        //~^ ERROR named arguments cannot follow explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("{a}", in("x0") foo, a = const bar);
+        //~^ ERROR named arguments cannot follow explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("{1}", in("x0") foo, const bar);
+        //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", options(), "");
+        //~^ ERROR expected one of
+        asm!("{}", in(reg) foo, "{}", out(reg) foo);
+        //~^ ERROR expected one of
+        asm!(format!("{{{}}}", 0), in(reg) foo);
+        //~^ ERROR asm template must be a string literal
+        asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
+        //~^ ERROR asm template must be a string literal
+        asm!("{}", in(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inlateout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+    }
+}
+
+const FOO: i32 = 1;
+const BAR: i32 = 2;
+global_asm!();
+//~^ ERROR requires at least a template string argument
+global_asm!(FOO);
+//~^ ERROR asm template must be a string literal
+global_asm!("{}" FOO);
+//~^ ERROR expected token: `,`
+global_asm!("{}", FOO);
+//~^ ERROR expected operand, options, or additional template string
+global_asm!("{}", const);
+//~^ ERROR expected expression, found end of macro arguments
+global_asm!("{}", const(reg) FOO);
+//~^ ERROR expected one of
+global_asm!("", options(FOO));
+//~^ ERROR expected one of
+global_asm!("", options(nomem FOO));
+//~^ ERROR expected one of
+global_asm!("", options(nomem, FOO));
+//~^ ERROR expected one of
+global_asm!("{}", options(), const FOO);
+//~^ ERROR arguments are not allowed after options
+global_asm!("", clobber_abi(FOO));
+//~^ ERROR expected string literal
+global_asm!("", clobber_abi("C" FOO));
+//~^ ERROR expected `)`, found `FOO`
+global_asm!("", clobber_abi("C", FOO));
+//~^ ERROR expected `)`, found `,`
+global_asm!("{}", clobber_abi("C"), const FOO);
+//~^ ERROR arguments are not allowed after clobber_abi
+//~^^ ERROR `clobber_abi` cannot be used with `global_asm!`
+global_asm!("", options(), clobber_abi("C"));
+//~^ ERROR clobber_abi is not allowed after options
+global_asm!("{}", options(), clobber_abi("C"), const FOO);
+//~^ ERROR clobber_abi is not allowed after options
+global_asm!("", clobber_abi("C"), clobber_abi("C"));
+//~^ ERROR clobber_abi specified multiple times
+global_asm!("{a}", a = const FOO, a = const BAR);
+//~^ ERROR duplicate argument named `a`
+//~^^ ERROR argument never used
+global_asm!("", options(), "");
+//~^ ERROR expected one of
+global_asm!("{}", const FOO, "{}", const FOO);
+//~^ ERROR expected one of
+global_asm!(format!("{{{}}}", 0), const FOO);
+//~^ ERROR asm template must be a string literal
+global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
+//~^ ERROR asm template must be a string literal
diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr
new file mode 100644 (file)
index 0000000..7b9fa90
--- /dev/null
@@ -0,0 +1,462 @@
+error: requires at least a template string argument
+  --> $DIR/parse-error.rs:9:9
+   |
+LL |         asm!();
+   |         ^^^^^^^
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:11:14
+   |
+LL |         asm!(foo);
+   |              ^^^
+
+error: expected token: `,`
+  --> $DIR/parse-error.rs:13:19
+   |
+LL |         asm!("{}" foo);
+   |                   ^^^ expected `,`
+
+error: expected operand, clobber_abi, options, or additional template string
+  --> $DIR/parse-error.rs:15:20
+   |
+LL |         asm!("{}", foo);
+   |                    ^^^ expected operand, clobber_abi, options, or additional template string
+
+error: expected `(`, found `foo`
+  --> $DIR/parse-error.rs:17:23
+   |
+LL |         asm!("{}", in foo);
+   |                       ^^^ expected `(`
+
+error: expected `)`, found `foo`
+  --> $DIR/parse-error.rs:19:27
+   |
+LL |         asm!("{}", in(reg foo));
+   |                           ^^^ expected `)`
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:21:27
+   |
+LL |         asm!("{}", in(reg));
+   |                           ^ expected expression
+
+error: expected register class or explicit register
+  --> $DIR/parse-error.rs:23:26
+   |
+LL |         asm!("{}", inout(=) foo => bar);
+   |                          ^
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:25:37
+   |
+LL |         asm!("{}", inout(reg) foo =>);
+   |                                     ^ expected expression
+
+error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
+  --> $DIR/parse-error.rs:27:32
+   |
+LL |         asm!("{}", in(reg) foo => bar);
+   |                                ^^ expected one of 7 possible tokens
+
+error: argument to `sym` must be a path expression
+  --> $DIR/parse-error.rs:29:24
+   |
+LL |         asm!("{}", sym foo + bar);
+   |                        ^^^^^^^^^
+
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
+  --> $DIR/parse-error.rs:31:26
+   |
+LL |         asm!("", options(foo));
+   |                          ^^^ expected one of 9 possible tokens
+
+error: expected one of `)` or `,`, found `foo`
+  --> $DIR/parse-error.rs:33:32
+   |
+LL |         asm!("", options(nomem foo));
+   |                                ^^^ expected one of `)` or `,`
+
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
+  --> $DIR/parse-error.rs:35:33
+   |
+LL |         asm!("", options(nomem, foo));
+   |                                 ^^^ expected one of 9 possible tokens
+
+error: arguments are not allowed after options
+  --> $DIR/parse-error.rs:37:31
+   |
+LL |         asm!("{}", options(), const foo);
+   |                    ---------  ^^^^^^^^^ argument
+   |                    |
+   |                    previous options
+
+error: expected string literal
+  --> $DIR/parse-error.rs:40:30
+   |
+LL |         asm!("", clobber_abi(foo));
+   |                              ^^^ not a string literal
+
+error: expected `)`, found `foo`
+  --> $DIR/parse-error.rs:42:34
+   |
+LL |         asm!("", clobber_abi("C" foo));
+   |                                  ^^^ expected `)`
+
+error: expected `)`, found `,`
+  --> $DIR/parse-error.rs:44:33
+   |
+LL |         asm!("", clobber_abi("C", foo));
+   |                                 ^ expected `)`
+
+error: arguments are not allowed after clobber_abi
+  --> $DIR/parse-error.rs:46:38
+   |
+LL |         asm!("{}", clobber_abi("C"), const foo);
+   |                    ----------------  ^^^^^^^^^ argument
+   |                    |
+   |                    clobber_abi
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:49:29
+   |
+LL |         asm!("", options(), clobber_abi("C"));
+   |                  ---------  ^^^^^^^^^^^^^^^^
+   |                  |
+   |                  options
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:51:31
+   |
+LL |         asm!("{}", options(), clobber_abi("C"), const foo);
+   |                    ---------  ^^^^^^^^^^^^^^^^
+   |                    |
+   |                    options
+
+error: clobber_abi specified multiple times
+  --> $DIR/parse-error.rs:53:36
+   |
+LL |         asm!("", clobber_abi("C"), clobber_abi("C"));
+   |                  ----------------  ^^^^^^^^^^^^^^^^
+   |                  |
+   |                  clobber_abi previously specified here
+
+error: duplicate argument named `a`
+  --> $DIR/parse-error.rs:55:36
+   |
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                     -------------  ^^^^^^^^^^^^^ duplicate argument
+   |                     |
+   |                     previously here
+
+error: argument never used
+  --> $DIR/parse-error.rs:55:36
+   |
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                                    ^^^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
+
+error: explicit register arguments cannot have names
+  --> $DIR/parse-error.rs:60:18
+   |
+LL |         asm!("", a = in("x0") foo);
+   |                  ^^^^^^^^^^^^^^^^
+
+error: named arguments cannot follow explicit register arguments
+  --> $DIR/parse-error.rs:62:35
+   |
+LL |         asm!("{a}", in("x0") foo, a = const bar);
+   |                     ------------  ^^^^^^^^^^^^^ named argument
+   |                     |
+   |                     explicit register argument
+
+error: named arguments cannot follow explicit register arguments
+  --> $DIR/parse-error.rs:65:35
+   |
+LL |         asm!("{a}", in("x0") foo, a = const bar);
+   |                     ------------  ^^^^^^^^^^^^^ named argument
+   |                     |
+   |                     explicit register argument
+
+error: positional arguments cannot follow named arguments or explicit register arguments
+  --> $DIR/parse-error.rs:68:35
+   |
+LL |         asm!("{1}", in("x0") foo, const bar);
+   |                     ------------  ^^^^^^^^^ positional argument
+   |                     |
+   |                     explicit register argument
+
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
+  --> $DIR/parse-error.rs:71:29
+   |
+LL |         asm!("", options(), "");
+   |                             ^^ expected one of 9 possible tokens
+
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
+  --> $DIR/parse-error.rs:73:33
+   |
+LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
+   |                                 ^^^^ expected one of 9 possible tokens
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:75:14
+   |
+LL |         asm!(format!("{{{}}}", 0), in(reg) foo);
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:77:21
+   |
+LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
+   |                     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:79:28
+   |
+LL |         asm!("{}", in(reg) _);
+   |                            ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:81:31
+   |
+LL |         asm!("{}", inout(reg) _);
+   |                               ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:83:35
+   |
+LL |         asm!("{}", inlateout(reg) _);
+   |                                   ^
+
+error: requires at least a template string argument
+  --> $DIR/parse-error.rs:90:1
+   |
+LL | global_asm!();
+   | ^^^^^^^^^^^^^^
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:92:13
+   |
+LL | global_asm!(FOO);
+   |             ^^^
+
+error: expected token: `,`
+  --> $DIR/parse-error.rs:94:18
+   |
+LL | global_asm!("{}" FOO);
+   |                  ^^^ expected `,`
+
+error: expected operand, options, or additional template string
+  --> $DIR/parse-error.rs:96:19
+   |
+LL | global_asm!("{}", FOO);
+   |                   ^^^ expected operand, options, or additional template string
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:98:24
+   |
+LL | global_asm!("{}", const);
+   |                        ^ expected expression
+
+error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
+  --> $DIR/parse-error.rs:100:30
+   |
+LL | global_asm!("{}", const(reg) FOO);
+   |                              ^^^ expected one of `,`, `.`, `?`, or an operator
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
+  --> $DIR/parse-error.rs:102:25
+   |
+LL | global_asm!("", options(FOO));
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/parse-error.rs:104:25
+   |
+LL | global_asm!("", options(nomem FOO));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/parse-error.rs:106:25
+   |
+LL | global_asm!("", options(nomem, FOO));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: arguments are not allowed after options
+  --> $DIR/parse-error.rs:108:30
+   |
+LL | global_asm!("{}", options(), const FOO);
+   |                   ---------  ^^^^^^^^^ argument
+   |                   |
+   |                   previous options
+
+error: expected string literal
+  --> $DIR/parse-error.rs:110:29
+   |
+LL | global_asm!("", clobber_abi(FOO));
+   |                             ^^^ not a string literal
+
+error: expected `)`, found `FOO`
+  --> $DIR/parse-error.rs:112:33
+   |
+LL | global_asm!("", clobber_abi("C" FOO));
+   |                                 ^^^ expected `)`
+
+error: expected `)`, found `,`
+  --> $DIR/parse-error.rs:114:32
+   |
+LL | global_asm!("", clobber_abi("C", FOO));
+   |                                ^ expected `)`
+
+error: arguments are not allowed after clobber_abi
+  --> $DIR/parse-error.rs:116:37
+   |
+LL | global_asm!("{}", clobber_abi("C"), const FOO);
+   |                   ----------------  ^^^^^^^^^ argument
+   |                   |
+   |                   clobber_abi
+
+error: `clobber_abi` cannot be used with `global_asm!`
+  --> $DIR/parse-error.rs:116:19
+   |
+LL | global_asm!("{}", clobber_abi("C"), const FOO);
+   |                   ^^^^^^^^^^^^^^^^
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:119:28
+   |
+LL | global_asm!("", options(), clobber_abi("C"));
+   |                 ---------  ^^^^^^^^^^^^^^^^
+   |                 |
+   |                 options
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:121:30
+   |
+LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
+   |                   ---------  ^^^^^^^^^^^^^^^^
+   |                   |
+   |                   options
+
+error: clobber_abi specified multiple times
+  --> $DIR/parse-error.rs:123:35
+   |
+LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
+   |                 ----------------  ^^^^^^^^^^^^^^^^
+   |                 |
+   |                 clobber_abi previously specified here
+
+error: duplicate argument named `a`
+  --> $DIR/parse-error.rs:125:35
+   |
+LL | global_asm!("{a}", a = const FOO, a = const BAR);
+   |                    -------------  ^^^^^^^^^^^^^ duplicate argument
+   |                    |
+   |                    previously here
+
+error: argument never used
+  --> $DIR/parse-error.rs:125:35
+   |
+LL | global_asm!("{a}", a = const FOO, a = const BAR);
+   |                                   ^^^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
+
+error: expected one of `clobber_abi`, `const`, or `options`, found `""`
+  --> $DIR/parse-error.rs:128:28
+   |
+LL | global_asm!("", options(), "");
+   |                            ^^ expected one of `clobber_abi`, `const`, or `options`
+
+error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
+  --> $DIR/parse-error.rs:130:30
+   |
+LL | global_asm!("{}", const FOO, "{}", const FOO);
+   |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:132:13
+   |
+LL | global_asm!(format!("{{{}}}", 0), const FOO);
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:134:20
+   |
+LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
+   |                    ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:37:37
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{}", options(), const foo);
+   |                                     ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:46:44
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{}", clobber_abi("C"), const foo);
+   |                                            ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:55:31
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                               ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:55:46
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:62:45
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("x0") foo, a = const bar);
+   |                                             ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:65:45
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("x0") foo, a = const bar);
+   |                                             ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:68:41
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{1}", in("x0") foo, const bar);
+   |                                         ^^^ non-constant value
+
+error: aborting due to 66 previous errors
+
+For more information about this error, try `rustc --explain E0435`.
diff --git a/src/test/ui/asm/aarch64/srcloc.rs b/src/test/ui/asm/aarch64/srcloc.rs
new file mode 100644 (file)
index 0000000..58feb52
--- /dev/null
@@ -0,0 +1,121 @@
+// min-llvm-version: 10.0.1
+// only-aarch64
+// build-fail
+// compile-flags: -Ccodegen-units=1
+#![feature(asm)]
+
+// Checks that inline asm errors are mapped to the correct line in the source code.
+
+fn main() {
+    unsafe {
+        asm!("invalid_instruction");
+        //~^ ERROR: unrecognized instruction mnemonic
+
+        asm!("
+            invalid_instruction
+        ");
+        //~^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(r#"
+            invalid_instruction
+        "#);
+        //~^^ ERROR: unrecognized instruction mnemonic
+
+        asm!("
+            mov x0, x0
+            invalid_instruction
+            mov x0, x0
+        ");
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(r#"
+            mov x0, x0
+            invalid_instruction
+            mov x0, x0
+        "#);
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(concat!("invalid", "_", "instruction"));
+        //~^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            "invalid_instruction",
+        );
+        //~^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            "mov x0, x0",
+            "invalid_instruction",
+            "mov x0, x0",
+        );
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            "mov x0, x0\n",
+            "invalid_instruction",
+            "mov x0, x0",
+        );
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            "mov x0, x0",
+            concat!("invalid", "_", "instruction"),
+            "mov x0, x0",
+        );
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            concat!("mov x0", ", ", "x0"),
+            concat!("invalid", "_", "instruction"),
+            concat!("mov x0", ", ", "x0"),
+        );
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        // Make sure template strings get separated
+        asm!(
+            "invalid_instruction1",
+            "invalid_instruction2",
+        );
+        //~^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2",
+            ),
+        );
+        //~^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2",
+            ),
+            concat!(
+                "invalid", "_", "instruction3", "\n",
+                "invalid", "_", "instruction4",
+            ),
+        );
+        //~^^^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^^ ERROR: unrecognized instruction mnemonic
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2", "\n",
+            ),
+            concat!(
+                "invalid", "_", "instruction3", "\n",
+                "invalid", "_", "instruction4", "\n",
+            ),
+        );
+        //~^^^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^ ERROR: unrecognized instruction mnemonic
+        //~^^^^^^^^ ERROR: unrecognized instruction mnemonic
+    }
+}
diff --git a/src/test/ui/asm/aarch64/srcloc.stderr b/src/test/ui/asm/aarch64/srcloc.stderr
new file mode 100644 (file)
index 0000000..96dab1b
--- /dev/null
@@ -0,0 +1,278 @@
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:11:15
+   |
+LL |         asm!("invalid_instruction");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:15:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:20:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:26:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:33:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:38:14
+   |
+LL |         asm!(concat!("invalid", "_", "instruction"));
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:42:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:48:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:55:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:62:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:69:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:76:14
+   |
+LL |             "invalid_instruction1",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:77:14
+   |
+LL |             "invalid_instruction2",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:83:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:83:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:92:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:92:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:96:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction3
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:96:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction4
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:107:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:2
+   |
+LL |     invalid_instruction1
+   |     ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:107:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:1
+   |
+LL | invalid_instruction2
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:111:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction3
+   | ^
+
+error: unrecognized instruction mnemonic
+  --> $DIR/srcloc.rs:111:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction4
+   | ^
+
+error: aborting due to 23 previous errors
+
diff --git a/src/test/ui/asm/aarch64/sym.rs b/src/test/ui/asm/aarch64/sym.rs
new file mode 100644 (file)
index 0000000..db732e9
--- /dev/null
@@ -0,0 +1,80 @@
+// min-llvm-version: 10.0.1
+// only-aarch64
+// only-linux
+// run-pass
+
+#![feature(asm, thread_local)]
+
+extern "C" fn f1() -> i32 {
+    111
+}
+
+// The compiler will generate a shim to hide the caller location parameter.
+#[track_caller]
+fn f2() -> i32 {
+    222
+}
+
+macro_rules! call {
+    ($func:path) => {
+        unsafe {
+            let result: i32;
+            asm!("bl {}", sym $func,
+                out("w0") result,
+                out("x20") _, out("x21") _, out("x22") _,
+                out("x23") _, out("x24") _, out("x25") _,
+                out("x26") _, out("x27") _, out("x28") _,
+            );
+            result
+        }
+    }
+}
+
+macro_rules! static_addr {
+    ($s:expr) => {
+        unsafe {
+            let result: *const u32;
+            asm!(
+                // ADRP gives the address of a 4KB page from a PC-relative address
+                "adrp {out}, {sym}",
+                // We then add the remaining lower 12 bits
+                "add {out}, {out}, #:lo12:{sym}",
+                out = out(reg) result,
+                sym = sym $s);
+            result
+        }
+    }
+}
+macro_rules! static_tls_addr {
+    ($s:expr) => {
+        unsafe {
+            let result: *const u32;
+            asm!(
+                // Load the thread pointer register
+                "mrs {out}, TPIDR_EL0",
+                // Add the top 12 bits of the symbol's offset
+                "add {out}, {out}, :tprel_hi12:{sym}",
+                // And the bottom 12 bits
+                "add {out}, {out}, :tprel_lo12:{sym}",
+                out = out(reg) result,
+                sym = sym $s
+            );
+            result
+        }
+    }
+}
+
+static S1: u32 = 111;
+#[thread_local]
+static S2: u32 = 222;
+
+fn main() {
+    assert_eq!(call!(f1), 111);
+    assert_eq!(call!(f2), 222);
+    assert_eq!(static_addr!(S1), &S1 as *const u32);
+    assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
+    std::thread::spawn(|| {
+        assert_eq!(static_addr!(S1), &S1 as *const u32);
+        assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
+    }).join().unwrap();
+}
diff --git a/src/test/ui/asm/aarch64/type-check-2.rs b/src/test/ui/asm/aarch64/type-check-2.rs
new file mode 100644 (file)
index 0000000..cf25dcb
--- /dev/null
@@ -0,0 +1,84 @@
+// only-aarch64
+
+#![feature(asm, repr_simd, never_type)]
+
+#[repr(simd)]
+#[derive(Clone, Copy)]
+struct SimdType(f32, f32, f32, f32);
+
+#[repr(simd)]
+struct SimdNonCopy(f32, f32, f32, f32);
+
+fn main() {
+    unsafe {
+        // Inputs must be initialized
+
+        let x: u64;
+        asm!("{}", in(reg) x);
+        //~^ ERROR use of possibly-uninitialized variable: `x`
+        let mut y: u64;
+        asm!("{}", inout(reg) y);
+        //~^ ERROR use of possibly-uninitialized variable: `y`
+        let _ = y;
+
+        // Outputs require mutable places
+
+        let v: Vec<u64> = vec![0, 1, 2];
+        asm!("{}", in(reg) v[0]);
+        asm!("{}", out(reg) v[0]);
+        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
+        asm!("{}", inout(reg) v[0]);
+        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
+
+        // Sym operands must point to a function or static
+
+        const C: i32 = 0;
+        static S: i32 = 0;
+        asm!("{}", sym S);
+        asm!("{}", sym main);
+        asm!("{}", sym C);
+        //~^ ERROR asm `sym` operand must point to a fn or static
+        asm!("{}", sym x);
+        //~^ ERROR asm `sym` operand must point to a fn or static
+
+        // Register operands must be Copy
+
+        asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+        //~^ ERROR arguments for inline assembly must be copyable
+
+        // Register operands must be integers, floats, SIMD vectors, pointers or
+        // function pointers.
+
+        asm!("{}", in(reg) 0i64);
+        asm!("{}", in(reg) 0f64);
+        asm!("{:v}", in(vreg) SimdType(0.0, 0.0, 0.0, 0.0));
+        asm!("{}", in(reg) 0 as *const u8);
+        asm!("{}", in(reg) 0 as *mut u8);
+        asm!("{}", in(reg) main as fn());
+        asm!("{}", in(reg) |x: i32| x);
+        //~^ ERROR cannot use value of type
+        asm!("{}", in(reg) vec![0]);
+        //~^ ERROR cannot use value of type `Vec<i32>` for inline assembly
+        asm!("{}", in(reg) (1, 2, 3));
+        //~^ ERROR cannot use value of type `(i32, i32, i32)` for inline assembly
+        asm!("{}", in(reg) [1, 2, 3]);
+        //~^ ERROR cannot use value of type `[i32; 3]` for inline assembly
+
+        // Register inputs (but not outputs) allow references and function types
+
+        let mut f = main;
+        let mut r = &mut 0;
+        asm!("{}", in(reg) f);
+        asm!("{}", inout(reg) f);
+        //~^ ERROR cannot use value of type `fn() {main}` for inline assembly
+        asm!("{}", in(reg) r);
+        asm!("{}", inout(reg) r);
+        //~^ ERROR cannot use value of type `&mut i32` for inline assembly
+        let _ = (f, r);
+
+        // Type checks ignore never type
+
+        let u: ! = unreachable!();
+        asm!("{}", in(reg) u);
+    }
+}
diff --git a/src/test/ui/asm/aarch64/type-check-2.stderr b/src/test/ui/asm/aarch64/type-check-2.stderr
new file mode 100644 (file)
index 0000000..e820906
--- /dev/null
@@ -0,0 +1,103 @@
+error: arguments for inline assembly must be copyable
+  --> $DIR/type-check-2.rs:46:31
+   |
+LL |         asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `SimdNonCopy` does not implement the Copy trait
+
+error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly
+  --> $DIR/type-check-2.rs:58:28
+   |
+LL |         asm!("{}", in(reg) |x: i32| x);
+   |                            ^^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `Vec<i32>` for inline assembly
+  --> $DIR/type-check-2.rs:60:28
+   |
+LL |         asm!("{}", in(reg) vec![0]);
+   |                            ^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot use value of type `(i32, i32, i32)` for inline assembly
+  --> $DIR/type-check-2.rs:62:28
+   |
+LL |         asm!("{}", in(reg) (1, 2, 3));
+   |                            ^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `[i32; 3]` for inline assembly
+  --> $DIR/type-check-2.rs:64:28
+   |
+LL |         asm!("{}", in(reg) [1, 2, 3]);
+   |                            ^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `fn() {main}` for inline assembly
+  --> $DIR/type-check-2.rs:72:31
+   |
+LL |         asm!("{}", inout(reg) f);
+   |                               ^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `&mut i32` for inline assembly
+  --> $DIR/type-check-2.rs:75:31
+   |
+LL |         asm!("{}", inout(reg) r);
+   |                               ^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: asm `sym` operand must point to a fn or static
+  --> $DIR/type-check-2.rs:39:24
+   |
+LL |         asm!("{}", sym C);
+   |                        ^
+
+error: asm `sym` operand must point to a fn or static
+  --> $DIR/type-check-2.rs:41:24
+   |
+LL |         asm!("{}", sym x);
+   |                        ^
+
+error[E0381]: use of possibly-uninitialized variable: `x`
+  --> $DIR/type-check-2.rs:17:28
+   |
+LL |         asm!("{}", in(reg) x);
+   |                            ^ use of possibly-uninitialized `x`
+
+error[E0381]: use of possibly-uninitialized variable: `y`
+  --> $DIR/type-check-2.rs:20:9
+   |
+LL |         asm!("{}", inout(reg) y);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
+
+error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
+  --> $DIR/type-check-2.rs:28:29
+   |
+LL |         let v: Vec<u64> = vec![0, 1, 2];
+   |             - help: consider changing this to be mutable: `mut v`
+LL |         asm!("{}", in(reg) v[0]);
+LL |         asm!("{}", out(reg) v[0]);
+   |                             ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
+  --> $DIR/type-check-2.rs:30:31
+   |
+LL |         let v: Vec<u64> = vec![0, 1, 2];
+   |             - help: consider changing this to be mutable: `mut v`
+...
+LL |         asm!("{}", inout(reg) v[0]);
+   |                               ^ cannot borrow as mutable
+
+error: aborting due to 13 previous errors
+
+Some errors have detailed explanations: E0381, E0596.
+For more information about an error, try `rustc --explain E0381`.
diff --git a/src/test/ui/asm/aarch64/type-check-3.rs b/src/test/ui/asm/aarch64/type-check-3.rs
new file mode 100644 (file)
index 0000000..d0d5954
--- /dev/null
@@ -0,0 +1,115 @@
+// only-aarch64
+// compile-flags: -C target-feature=+neon
+
+#![feature(asm, global_asm, repr_simd, stdsimd)]
+
+use std::arch::aarch64::float64x2_t;
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct Simd256bit(f64, f64,f64, f64);
+
+fn main() {
+    let f64x2: float64x2_t = unsafe { std::mem::transmute(0i128) };
+    let f64x4 = Simd256bit(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        // Types must be listed in the register class.
+
+        // Success cases
+        asm!("{:w}", in(reg) 0u8);
+        asm!("{:w}", in(reg) 0u16);
+        asm!("{:w}", in(reg) 0u32);
+        asm!("{:w}", in(reg) 0f32);
+        asm!("{}", in(reg) 0i64);
+        asm!("{}", in(reg) 0f64);
+
+        asm!("{:b}", in(vreg) 0u8);
+        asm!("{:h}", in(vreg) 0u16);
+        asm!("{:s}", in(vreg) 0u32);
+        asm!("{:s}", in(vreg) 0f32);
+        asm!("{:d}", in(vreg) 0u64);
+        asm!("{:d}", in(vreg) 0f64);
+        asm!("{:q}", in(vreg) f64x2);
+        asm!("{:v}", in(vreg) f64x2);
+
+        // Should be the same as vreg
+        asm!("{:q}", in(vreg_low16) f64x2);
+
+        // Template modifiers of a different size to the argument are fine
+        asm!("{:w}", in(reg) 0u64);
+        asm!("{:x}", in(reg) 0u32);
+        asm!("{:b}", in(vreg) 0u64);
+        asm!("{:d}", in(vreg_low16) f64x2);
+
+
+        // Template modifier suggestions for sub-registers
+
+        asm!("{}", in(reg) 0u8);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(reg) 0u16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(reg) 0i32);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(reg) 0f32);
+        //~^ WARN formatting may not be suitable for sub-register argument
+
+        asm!("{}", in(vreg) 0i16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(vreg) 0f32);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(vreg) 0f64);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(vreg_low16) 0f64);
+        //~^ WARN formatting may not be suitable for sub-register argument
+
+        asm!("{0} {0}", in(reg) 0i16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{0} {0:x}", in(reg) 0i16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+
+        // Invalid registers
+
+        asm!("{}", in(reg) 0i128);
+        //~^ ERROR type `i128` cannot be used with this register class
+        asm!("{}", in(reg) f64x2);
+        //~^ ERROR type `float64x2_t` cannot be used with this register class
+        asm!("{}", in(vreg) f64x4);
+        //~^ ERROR type `Simd256bit` cannot be used with this register class
+
+        // Split inout operands must have compatible types
+
+        let mut val_i16: i16;
+        let mut val_f32: f32;
+        let mut val_u32: u32;
+        let mut val_u64: u64;
+        let mut val_ptr: *mut u8;
+        asm!("{:x}", inout(reg) 0u16 => val_i16);
+        asm!("{:x}", inout(reg) 0u32 => val_f32);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:x}", inout(reg) 0u32 => val_ptr);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:x}", inout(reg) main => val_u32);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:x}", inout(reg) 0u64 => val_ptr);
+        asm!("{:x}", inout(reg) main => val_u64);
+    }
+}
+
+// Constants must be... constant
+
+static S: i32 = 1;
+const fn const_foo(x: i32) -> i32 {
+    x
+}
+const fn const_bar<T>(x: T) -> T {
+    x
+}
+global_asm!("{}", const S);
+//~^ ERROR constants cannot refer to statics
+global_asm!("{}", const const_foo(0));
+global_asm!("{}", const const_foo(S));
+//~^ ERROR constants cannot refer to statics
+global_asm!("{}", const const_bar(0));
+global_asm!("{}", const const_bar(S));
+//~^ ERROR constants cannot refer to statics
diff --git a/src/test/ui/asm/aarch64/type-check-3.stderr b/src/test/ui/asm/aarch64/type-check-3.stderr
new file mode 100644 (file)
index 0000000..c31a62a
--- /dev/null
@@ -0,0 +1,172 @@
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:48:15
+   |
+LL |         asm!("{}", in(reg) 0u8);
+   |               ^^           --- for this argument
+   |
+   = note: `#[warn(asm_sub_register)]` on by default
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:50:15
+   |
+LL |         asm!("{}", in(reg) 0u16);
+   |               ^^           ---- for this argument
+   |
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:52:15
+   |
+LL |         asm!("{}", in(reg) 0i32);
+   |               ^^           ---- for this argument
+   |
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:54:15
+   |
+LL |         asm!("{}", in(reg) 0f32);
+   |               ^^           ---- for this argument
+   |
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:57:15
+   |
+LL |         asm!("{}", in(vreg) 0i16);
+   |               ^^            ---- for this argument
+   |
+   = help: use the `h` modifier to have the register formatted as `h0`
+   = help: or use the `v` modifier to keep the default formatting of `v0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:59:15
+   |
+LL |         asm!("{}", in(vreg) 0f32);
+   |               ^^            ---- for this argument
+   |
+   = help: use the `s` modifier to have the register formatted as `s0`
+   = help: or use the `v` modifier to keep the default formatting of `v0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:61:15
+   |
+LL |         asm!("{}", in(vreg) 0f64);
+   |               ^^            ---- for this argument
+   |
+   = help: use the `d` modifier to have the register formatted as `d0`
+   = help: or use the `v` modifier to keep the default formatting of `v0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:63:15
+   |
+LL |         asm!("{}", in(vreg_low16) 0f64);
+   |               ^^                  ---- for this argument
+   |
+   = help: use the `d` modifier to have the register formatted as `d0`
+   = help: or use the `v` modifier to keep the default formatting of `v0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:66:15
+   |
+LL |         asm!("{0} {0}", in(reg) 0i16);
+   |               ^^^ ^^^           ---- for this argument
+   |
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:68:15
+   |
+LL |         asm!("{0} {0:x}", in(reg) 0i16);
+   |               ^^^                 ---- for this argument
+   |
+   = help: use the `w` modifier to have the register formatted as `w0`
+   = help: or use the `x` modifier to keep the default formatting of `x0`
+
+error: type `i128` cannot be used with this register class
+  --> $DIR/type-check-3.rs:73:28
+   |
+LL |         asm!("{}", in(reg) 0i128);
+   |                            ^^^^^
+   |
+   = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
+
+error: type `float64x2_t` cannot be used with this register class
+  --> $DIR/type-check-3.rs:75:28
+   |
+LL |         asm!("{}", in(reg) f64x2);
+   |                            ^^^^^
+   |
+   = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
+
+error: type `Simd256bit` cannot be used with this register class
+  --> $DIR/type-check-3.rs:77:29
+   |
+LL |         asm!("{}", in(vreg) f64x4);
+   |                             ^^^^^
+   |
+   = note: register class `vreg` supports these types: i8, i16, i32, i64, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:88:33
+   |
+LL |         asm!("{:x}", inout(reg) 0u32 => val_f32);
+   |                                 ^^^^    ^^^^^^^ type `f32`
+   |                                 |
+   |                                 type `u32`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:90:33
+   |
+LL |         asm!("{:x}", inout(reg) 0u32 => val_ptr);
+   |                                 ^^^^    ^^^^^^^ type `*mut u8`
+   |                                 |
+   |                                 type `u32`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:92:33
+   |
+LL |         asm!("{:x}", inout(reg) main => val_u32);
+   |                                 ^^^^    ^^^^^^^ type `u32`
+   |                                 |
+   |                                 type `fn()`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:108:25
+   |
+LL | global_asm!("{}", const S);
+   |                         ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:111:35
+   |
+LL | global_asm!("{}", const const_foo(S));
+   |                                   ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:114:35
+   |
+LL | global_asm!("{}", const const_bar(S));
+   |                                   ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error: aborting due to 9 previous errors; 10 warnings emitted
+
+For more information about this error, try `rustc --explain E0013`.
diff --git a/src/test/ui/asm/bad-options.rs b/src/test/ui/asm/bad-options.rs
deleted file mode 100644 (file)
index dc61d16..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// only-x86_64
-
-#![feature(asm, global_asm)]
-
-fn main() {
-    let mut foo = 0;
-    unsafe {
-        asm!("", options(nomem, readonly));
-        //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
-        asm!("", options(pure, nomem, noreturn));
-        //~^ ERROR the `pure` and `noreturn` options are mutually exclusive
-        //~^^ ERROR asm with the `pure` option must have at least one output
-        asm!("{}", in(reg) foo, options(pure, nomem));
-        //~^ ERROR asm with the `pure` option must have at least one output
-        asm!("{}", out(reg) foo, options(noreturn));
-        //~^ ERROR asm outputs are not allowed with the `noreturn` option
-    }
-
-    unsafe {
-        asm!("", clobber_abi("foo"));
-        //~^ ERROR invalid ABI for `clobber_abi`
-        asm!("{}", out(reg) foo, clobber_abi("C"));
-        //~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs
-        asm!("", out("eax") foo, clobber_abi("C"));
-    }
-}
-
-global_asm!("", options(nomem));
-//~^ ERROR expected one of
-global_asm!("", options(readonly));
-//~^ ERROR expected one of
-global_asm!("", options(noreturn));
-//~^ ERROR expected one of
-global_asm!("", options(pure));
-//~^ ERROR expected one of
-global_asm!("", options(nostack));
-//~^ ERROR expected one of
-global_asm!("", options(preserves_flags));
-//~^ ERROR expected one of
diff --git a/src/test/ui/asm/bad-options.stderr b/src/test/ui/asm/bad-options.stderr
deleted file mode 100644 (file)
index 8cfd450..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-error: the `nomem` and `readonly` options are mutually exclusive
-  --> $DIR/bad-options.rs:8:18
-   |
-LL |         asm!("", options(nomem, readonly));
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: the `pure` and `noreturn` options are mutually exclusive
-  --> $DIR/bad-options.rs:10:18
-   |
-LL |         asm!("", options(pure, nomem, noreturn));
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: asm with the `pure` option must have at least one output
-  --> $DIR/bad-options.rs:10:18
-   |
-LL |         asm!("", options(pure, nomem, noreturn));
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: asm with the `pure` option must have at least one output
-  --> $DIR/bad-options.rs:13:33
-   |
-LL |         asm!("{}", in(reg) foo, options(pure, nomem));
-   |                                 ^^^^^^^^^^^^^^^^^^^^
-
-error: asm outputs are not allowed with the `noreturn` option
-  --> $DIR/bad-options.rs:15:20
-   |
-LL |         asm!("{}", out(reg) foo, options(noreturn));
-   |                    ^^^^^^^^^^^^
-
-error: asm with `clobber_abi` must specify explicit registers for outputs
-  --> $DIR/bad-options.rs:22:20
-   |
-LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
-   |                    ^^^^^^^^^^^^  ---------------- clobber_abi
-   |                    |
-   |                    generic outputs
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/bad-options.rs:28:25
-   |
-LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
-  --> $DIR/bad-options.rs:30:25
-   |
-LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
-  --> $DIR/bad-options.rs:32:25
-   |
-LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
-  --> $DIR/bad-options.rs:34:25
-   |
-LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
-  --> $DIR/bad-options.rs:36:25
-   |
-LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
-  --> $DIR/bad-options.rs:38:25
-   |
-LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: invalid ABI for `clobber_abi`
-  --> $DIR/bad-options.rs:20:18
-   |
-LL |         asm!("", clobber_abi("foo"));
-   |                  ^^^^^^^^^^^^^^^^^^
-   |
-   = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
-
-error: aborting due to 13 previous errors
-
diff --git a/src/test/ui/asm/bad-reg.rs b/src/test/ui/asm/bad-reg.rs
deleted file mode 100644 (file)
index 06af08f..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// only-x86_64
-// compile-flags: -C target-feature=+avx2
-
-#![feature(asm)]
-
-fn main() {
-    let mut foo = 0;
-    let mut bar = 0;
-    unsafe {
-        // Bad register/register class
-
-        asm!("{}", in(foo) foo);
-        //~^ ERROR invalid register class `foo`: unknown register class
-        asm!("", in("foo") foo);
-        //~^ ERROR invalid register `foo`: unknown register
-        asm!("{:z}", in(reg) foo);
-        //~^ ERROR invalid asm template modifier for this register class
-        asm!("{:r}", in(xmm_reg) foo);
-        //~^ ERROR invalid asm template modifier for this register class
-        asm!("{:a}", const 0);
-        //~^ ERROR asm template modifiers are not allowed for `const` arguments
-        asm!("{:a}", sym main);
-        //~^ ERROR asm template modifiers are not allowed for `sym` arguments
-        asm!("{}", in(zmm_reg) foo);
-        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
-        asm!("", in("zmm0") foo);
-        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
-        asm!("", in("ebp") foo);
-        //~^ ERROR invalid register `ebp`: the frame pointer cannot be used as an operand
-        asm!("", in("rsp") foo);
-        //~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
-        asm!("", in("ip") foo);
-        //~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
-        asm!("", in("k0") foo);
-        //~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
-        asm!("", in("ah") foo);
-        //~^ ERROR invalid register `ah`: high byte registers cannot be used as an operand
-
-        asm!("", in("st(2)") foo);
-        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
-        asm!("", in("mm0") foo);
-        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
-        asm!("", out("st(2)") _);
-        asm!("", out("mm0") _);
-        asm!("{}", in(x87_reg) foo);
-        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
-        asm!("{}", in(mmx_reg) foo);
-        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
-        asm!("{}", out(x87_reg) _);
-        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
-        asm!("{}", out(mmx_reg) _);
-        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
-
-        // Explicit register conflicts
-        // (except in/lateout which don't conflict)
-
-        asm!("", in("eax") foo, in("al") bar);
-        //~^ ERROR register `al` conflicts with register `ax`
-        asm!("", in("rax") foo, out("rax") bar);
-        //~^ ERROR register `ax` conflicts with register `ax`
-        asm!("", in("al") foo, lateout("al") bar);
-        asm!("", in("xmm0") foo, in("ymm0") bar);
-        //~^ ERROR register `ymm0` conflicts with register `xmm0`
-        asm!("", in("xmm0") foo, out("ymm0") bar);
-        //~^ ERROR register `ymm0` conflicts with register `xmm0`
-        asm!("", in("xmm0") foo, lateout("ymm0") bar);
-    }
-}
diff --git a/src/test/ui/asm/bad-reg.stderr b/src/test/ui/asm/bad-reg.stderr
deleted file mode 100644 (file)
index 14740bf..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-error: invalid register class `foo`: unknown register class
-  --> $DIR/bad-reg.rs:12:20
-   |
-LL |         asm!("{}", in(foo) foo);
-   |                    ^^^^^^^^^^^
-
-error: invalid register `foo`: unknown register
-  --> $DIR/bad-reg.rs:14:18
-   |
-LL |         asm!("", in("foo") foo);
-   |                  ^^^^^^^^^^^^^
-
-error: invalid asm template modifier for this register class
-  --> $DIR/bad-reg.rs:16:15
-   |
-LL |         asm!("{:z}", in(reg) foo);
-   |               ^^^^   ----------- argument
-   |               |
-   |               template modifier
-   |
-   = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, `r`
-
-error: invalid asm template modifier for this register class
-  --> $DIR/bad-reg.rs:18:15
-   |
-LL |         asm!("{:r}", in(xmm_reg) foo);
-   |               ^^^^   --------------- argument
-   |               |
-   |               template modifier
-   |
-   = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, `z`
-
-error: asm template modifiers are not allowed for `const` arguments
-  --> $DIR/bad-reg.rs:20:15
-   |
-LL |         asm!("{:a}", const 0);
-   |               ^^^^   ------- argument
-   |               |
-   |               template modifier
-
-error: asm template modifiers are not allowed for `sym` arguments
-  --> $DIR/bad-reg.rs:22:15
-   |
-LL |         asm!("{:a}", sym main);
-   |               ^^^^   -------- argument
-   |               |
-   |               template modifier
-
-error: register class `zmm_reg` requires the `avx512f` target feature
-  --> $DIR/bad-reg.rs:24:20
-   |
-LL |         asm!("{}", in(zmm_reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: register class `zmm_reg` requires the `avx512f` target feature
-  --> $DIR/bad-reg.rs:26:18
-   |
-LL |         asm!("", in("zmm0") foo);
-   |                  ^^^^^^^^^^^^^^
-
-error: invalid register `ebp`: the frame pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:28:18
-   |
-LL |         asm!("", in("ebp") foo);
-   |                  ^^^^^^^^^^^^^
-
-error: invalid register `rsp`: the stack pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:30:18
-   |
-LL |         asm!("", in("rsp") foo);
-   |                  ^^^^^^^^^^^^^
-
-error: invalid register `ip`: the instruction pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:32:18
-   |
-LL |         asm!("", in("ip") foo);
-   |                  ^^^^^^^^^^^^
-
-error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:34:18
-   |
-LL |         asm!("", in("k0") foo);
-   |                  ^^^^^^^^^^^^
-
-error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64
-  --> $DIR/bad-reg.rs:36:18
-   |
-LL |         asm!("", in("ah") foo);
-   |                  ^^^^^^^^^^^^
-
-error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:39:18
-   |
-LL |         asm!("", in("st(2)") foo);
-   |                  ^^^^^^^^^^^^^^^
-
-error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:41:18
-   |
-LL |         asm!("", in("mm0") foo);
-   |                  ^^^^^^^^^^^^^
-
-error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:45:20
-   |
-LL |         asm!("{}", in(x87_reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:47:20
-   |
-LL |         asm!("{}", in(mmx_reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:49:20
-   |
-LL |         asm!("{}", out(x87_reg) _);
-   |                    ^^^^^^^^^^^^^^
-
-error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:51:20
-   |
-LL |         asm!("{}", out(mmx_reg) _);
-   |                    ^^^^^^^^^^^^^^
-
-error: register `al` conflicts with register `ax`
-  --> $DIR/bad-reg.rs:57:33
-   |
-LL |         asm!("", in("eax") foo, in("al") bar);
-   |                  -------------  ^^^^^^^^^^^^ register `al`
-   |                  |
-   |                  register `ax`
-
-error: register `ax` conflicts with register `ax`
-  --> $DIR/bad-reg.rs:59:33
-   |
-LL |         asm!("", in("rax") foo, out("rax") bar);
-   |                  -------------  ^^^^^^^^^^^^^^ register `ax`
-   |                  |
-   |                  register `ax`
-   |
-help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:59:18
-   |
-LL |         asm!("", in("rax") foo, out("rax") bar);
-   |                  ^^^^^^^^^^^^^
-
-error: register `ymm0` conflicts with register `xmm0`
-  --> $DIR/bad-reg.rs:62:34
-   |
-LL |         asm!("", in("xmm0") foo, in("ymm0") bar);
-   |                  --------------  ^^^^^^^^^^^^^^ register `ymm0`
-   |                  |
-   |                  register `xmm0`
-
-error: register `ymm0` conflicts with register `xmm0`
-  --> $DIR/bad-reg.rs:64:34
-   |
-LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
-   |                  --------------  ^^^^^^^^^^^^^^^ register `ymm0`
-   |                  |
-   |                  register `xmm0`
-   |
-help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:64:18
-   |
-LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
-   |                  ^^^^^^^^^^^^^^
-
-error: aborting due to 23 previous errors
-
diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..3b1d922
--- /dev/null
@@ -0,0 +1,187 @@
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:31:15
+   |
+LL |         asm!("{}");
+   |               ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:33:15
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:33:21
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |                     ^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:36:15
+   |
+LL |         asm!("{a}");
+   |               ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:38:15
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |               ^^   --------------- named argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:41:15
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:41:21
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |                     ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:48:15
+   |
+LL |         asm!("{}", in("x0") foo);
+   |               ^^   ------------ explicit register argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: explicit register arguments cannot be used in the asm template
+  --> $DIR/bad-template.rs:48:20
+   |
+LL |         asm!("{}", in("x0") foo);
+   |                    ^^^^^^^^^^^^
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:50:17
+   |
+LL |         asm!("{:foo}", in(reg) foo);
+   |                 ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:52:18
+   |
+LL |         asm!("", in(reg) 0, in(reg) 1);
+   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                  |
+   |                  argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:58:14
+   |
+LL | global_asm!("{}");
+   |              ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:60:14
+   |
+LL | global_asm!("{1}", const FOO);
+   |              ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:60:20
+   |
+LL | global_asm!("{1}", const FOO);
+   |                    ^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:63:14
+   |
+LL | global_asm!("{a}");
+   |              ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:65:14
+   |
+LL | global_asm!("{}", a = const FOO);
+   |              ^^   ------------- named argument
+   |              |
+   |              from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:68:14
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |              ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:68:20
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |                    ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:71:16
+   |
+LL | global_asm!("{:foo}", const FOO);
+   |                ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:73:17
+   |
+LL | global_asm!("", const FOO, const FOO);
+   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                 |
+   |                 argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: aborting due to 21 previous errors
+
diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..3b1d922
--- /dev/null
@@ -0,0 +1,187 @@
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:31:15
+   |
+LL |         asm!("{}");
+   |               ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:33:15
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:33:21
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |                     ^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:36:15
+   |
+LL |         asm!("{a}");
+   |               ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:38:15
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |               ^^   --------------- named argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:41:15
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:41:21
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |                     ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:48:15
+   |
+LL |         asm!("{}", in("x0") foo);
+   |               ^^   ------------ explicit register argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: explicit register arguments cannot be used in the asm template
+  --> $DIR/bad-template.rs:48:20
+   |
+LL |         asm!("{}", in("x0") foo);
+   |                    ^^^^^^^^^^^^
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:50:17
+   |
+LL |         asm!("{:foo}", in(reg) foo);
+   |                 ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:52:18
+   |
+LL |         asm!("", in(reg) 0, in(reg) 1);
+   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                  |
+   |                  argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:58:14
+   |
+LL | global_asm!("{}");
+   |              ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:60:14
+   |
+LL | global_asm!("{1}", const FOO);
+   |              ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:60:20
+   |
+LL | global_asm!("{1}", const FOO);
+   |                    ^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:63:14
+   |
+LL | global_asm!("{a}");
+   |              ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:65:14
+   |
+LL | global_asm!("{}", a = const FOO);
+   |              ^^   ------------- named argument
+   |              |
+   |              from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:68:14
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |              ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:68:20
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |                    ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:71:16
+   |
+LL | global_asm!("{:foo}", const FOO);
+   |                ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:73:17
+   |
+LL | global_asm!("", const FOO, const FOO);
+   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                 |
+   |                 argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: aborting due to 21 previous errors
+
diff --git a/src/test/ui/asm/bad-template.mirunsafeck.stderr b/src/test/ui/asm/bad-template.mirunsafeck.stderr
deleted file mode 100644 (file)
index 13ef032..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:10:15
-   |
-LL |         asm!("{}");
-   |               ^^ from here
-   |
-   = note: no arguments were given
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:12:15
-   |
-LL |         asm!("{1}", in(reg) foo);
-   |               ^^^ from here
-   |
-   = note: there is 1 argument
-
-error: argument never used
-  --> $DIR/bad-template.rs:12:21
-   |
-LL |         asm!("{1}", in(reg) foo);
-   |                     ^^^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
-
-error: there is no argument named `a`
-  --> $DIR/bad-template.rs:15:15
-   |
-LL |         asm!("{a}");
-   |               ^^^
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:17:15
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |               ^^   --------------- named argument
-   |               |
-   |               from here
-   |
-   = note: no positional arguments were given
-note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:17:20
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: named argument never used
-  --> $DIR/bad-template.rs:17:20
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |                    ^^^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:20:15
-   |
-LL |         asm!("{1}", a = in(reg) foo);
-   |               ^^^ from here
-   |
-   = note: no positional arguments were given
-
-error: named argument never used
-  --> $DIR/bad-template.rs:20:21
-   |
-LL |         asm!("{1}", a = in(reg) foo);
-   |                     ^^^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:23:15
-   |
-LL |         asm!("{}", in("eax") foo);
-   |               ^^   ------------- explicit register argument
-   |               |
-   |               from here
-   |
-   = note: no positional arguments were given
-note: explicit register arguments cannot be used in the asm template
-  --> $DIR/bad-template.rs:23:20
-   |
-LL |         asm!("{}", in("eax") foo);
-   |                    ^^^^^^^^^^^^^
-
-error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:25:17
-   |
-LL |         asm!("{:foo}", in(reg) foo);
-   |                 ^^^
-
-error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:27:18
-   |
-LL |         asm!("", in(reg) 0, in(reg) 1);
-   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
-   |                  |
-   |                  argument never used
-   |
-   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:33:14
-   |
-LL | global_asm!("{}");
-   |              ^^ from here
-   |
-   = note: no arguments were given
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:35:14
-   |
-LL | global_asm!("{1}", const FOO);
-   |              ^^^ from here
-   |
-   = note: there is 1 argument
-
-error: argument never used
-  --> $DIR/bad-template.rs:35:20
-   |
-LL | global_asm!("{1}", const FOO);
-   |                    ^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
-
-error: there is no argument named `a`
-  --> $DIR/bad-template.rs:38:14
-   |
-LL | global_asm!("{a}");
-   |              ^^^
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:40:14
-   |
-LL | global_asm!("{}", a = const FOO);
-   |              ^^   ------------- named argument
-   |              |
-   |              from here
-   |
-   = note: no positional arguments were given
-note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:40:19
-   |
-LL | global_asm!("{}", a = const FOO);
-   |                   ^^^^^^^^^^^^^
-
-error: named argument never used
-  --> $DIR/bad-template.rs:40:19
-   |
-LL | global_asm!("{}", a = const FOO);
-   |                   ^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:43:14
-   |
-LL | global_asm!("{1}", a = const FOO);
-   |              ^^^ from here
-   |
-   = note: no positional arguments were given
-
-error: named argument never used
-  --> $DIR/bad-template.rs:43:20
-   |
-LL | global_asm!("{1}", a = const FOO);
-   |                    ^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:46:16
-   |
-LL | global_asm!("{:foo}", const FOO);
-   |                ^^^
-
-error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:48:17
-   |
-LL | global_asm!("", const FOO, const FOO);
-   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
-   |                 |
-   |                 argument never used
-   |
-   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
-
-error: aborting due to 21 previous errors
-
index 5aed2c62f0bddaa29aa0bace25bc869dc64f660e..fca77e7aa71f37d9b3841cbaf4e9a1fe31793dd7 100644 (file)
@@ -1,8 +1,29 @@
-// only-x86_64
-// revisions: mirunsafeck thirunsafeck
-// [thirunsafeck]compile-flags: -Z thir-unsafeck
+// revisions: x86_64_mirunsafeck aarch64_mirunsafeck x86_64_thirunsafeck aarch64_thirunsafeck
 
-#![feature(asm, global_asm)]
+// [x86_64_thirunsafeck] compile-flags: -Z thir-unsafeck --target x86_64-unknown-linux-gnu
+// [aarch64_thirunsafeck] compile-flags: -Z thir-unsafeck --target aarch64-unknown-linux-gnu
+// [x86_64_mirunsafeck] compile-flags: --target x86_64-unknown-linux-gnu
+// [aarch64_mirunsafeck] compile-flags: --target aarch64-unknown-linux-gnu
+
+// [x86_64_thirunsafeck] needs-llvm-components: x86
+// [x86_64_mirunsafeck] needs-llvm-components: x86
+// [aarch64_thirunsafeck] needs-llvm-components: aarch64
+// [aarch64_mirunsafeck] needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+#[rustc_builtin_macro]
+macro_rules! global_asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
 
 fn main() {
     let mut foo = 0;
@@ -20,8 +41,12 @@ fn main() {
         asm!("{1}", a = in(reg) foo);
         //~^ ERROR invalid reference to argument at index 1
         //~^^ ERROR named argument never used
+        #[cfg(any(x86_64_thirunsafeck, x86_64_mirunsafeck))]
         asm!("{}", in("eax") foo);
-        //~^ ERROR invalid reference to argument at index 0
+        //[x86_64_thirunsafeck,x86_64_mirunsafeck]~^ ERROR invalid reference to argument at index 0
+        #[cfg(any(aarch64_thirunsafeck, aarch64_mirunsafeck))]
+        asm!("{}", in("x0") foo);
+        //[aarch64_thirunsafeck,aarch64_mirunsafeck]~^ ERROR invalid reference to argument at index 0
         asm!("{:foo}", in(reg) foo);
         //~^ ERROR asm template modifier must be a single character
         asm!("", in(reg) 0, in(reg) 1);
diff --git a/src/test/ui/asm/bad-template.thirunsafeck.stderr b/src/test/ui/asm/bad-template.thirunsafeck.stderr
deleted file mode 100644 (file)
index 13ef032..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:10:15
-   |
-LL |         asm!("{}");
-   |               ^^ from here
-   |
-   = note: no arguments were given
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:12:15
-   |
-LL |         asm!("{1}", in(reg) foo);
-   |               ^^^ from here
-   |
-   = note: there is 1 argument
-
-error: argument never used
-  --> $DIR/bad-template.rs:12:21
-   |
-LL |         asm!("{1}", in(reg) foo);
-   |                     ^^^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
-
-error: there is no argument named `a`
-  --> $DIR/bad-template.rs:15:15
-   |
-LL |         asm!("{a}");
-   |               ^^^
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:17:15
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |               ^^   --------------- named argument
-   |               |
-   |               from here
-   |
-   = note: no positional arguments were given
-note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:17:20
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: named argument never used
-  --> $DIR/bad-template.rs:17:20
-   |
-LL |         asm!("{}", a = in(reg) foo);
-   |                    ^^^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:20:15
-   |
-LL |         asm!("{1}", a = in(reg) foo);
-   |               ^^^ from here
-   |
-   = note: no positional arguments were given
-
-error: named argument never used
-  --> $DIR/bad-template.rs:20:21
-   |
-LL |         asm!("{1}", a = in(reg) foo);
-   |                     ^^^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:23:15
-   |
-LL |         asm!("{}", in("eax") foo);
-   |               ^^   ------------- explicit register argument
-   |               |
-   |               from here
-   |
-   = note: no positional arguments were given
-note: explicit register arguments cannot be used in the asm template
-  --> $DIR/bad-template.rs:23:20
-   |
-LL |         asm!("{}", in("eax") foo);
-   |                    ^^^^^^^^^^^^^
-
-error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:25:17
-   |
-LL |         asm!("{:foo}", in(reg) foo);
-   |                 ^^^
-
-error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:27:18
-   |
-LL |         asm!("", in(reg) 0, in(reg) 1);
-   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
-   |                  |
-   |                  argument never used
-   |
-   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:33:14
-   |
-LL | global_asm!("{}");
-   |              ^^ from here
-   |
-   = note: no arguments were given
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:35:14
-   |
-LL | global_asm!("{1}", const FOO);
-   |              ^^^ from here
-   |
-   = note: there is 1 argument
-
-error: argument never used
-  --> $DIR/bad-template.rs:35:20
-   |
-LL | global_asm!("{1}", const FOO);
-   |                    ^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
-
-error: there is no argument named `a`
-  --> $DIR/bad-template.rs:38:14
-   |
-LL | global_asm!("{a}");
-   |              ^^^
-
-error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:40:14
-   |
-LL | global_asm!("{}", a = const FOO);
-   |              ^^   ------------- named argument
-   |              |
-   |              from here
-   |
-   = note: no positional arguments were given
-note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:40:19
-   |
-LL | global_asm!("{}", a = const FOO);
-   |                   ^^^^^^^^^^^^^
-
-error: named argument never used
-  --> $DIR/bad-template.rs:40:19
-   |
-LL | global_asm!("{}", a = const FOO);
-   |                   ^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:43:14
-   |
-LL | global_asm!("{1}", a = const FOO);
-   |              ^^^ from here
-   |
-   = note: no positional arguments were given
-
-error: named argument never used
-  --> $DIR/bad-template.rs:43:20
-   |
-LL | global_asm!("{1}", a = const FOO);
-   |                    ^^^^^^^^^^^^^ named argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
-
-error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:46:16
-   |
-LL | global_asm!("{:foo}", const FOO);
-   |                ^^^
-
-error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:48:17
-   |
-LL | global_asm!("", const FOO, const FOO);
-   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
-   |                 |
-   |                 argument never used
-   |
-   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
-
-error: aborting due to 21 previous errors
-
diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..3b69186
--- /dev/null
@@ -0,0 +1,187 @@
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:31:15
+   |
+LL |         asm!("{}");
+   |               ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:33:15
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:33:21
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |                     ^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:36:15
+   |
+LL |         asm!("{a}");
+   |               ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:38:15
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |               ^^   --------------- named argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:41:15
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:41:21
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |                     ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:45:15
+   |
+LL |         asm!("{}", in("eax") foo);
+   |               ^^   ------------- explicit register argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: explicit register arguments cannot be used in the asm template
+  --> $DIR/bad-template.rs:45:20
+   |
+LL |         asm!("{}", in("eax") foo);
+   |                    ^^^^^^^^^^^^^
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:50:17
+   |
+LL |         asm!("{:foo}", in(reg) foo);
+   |                 ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:52:18
+   |
+LL |         asm!("", in(reg) 0, in(reg) 1);
+   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                  |
+   |                  argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:58:14
+   |
+LL | global_asm!("{}");
+   |              ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:60:14
+   |
+LL | global_asm!("{1}", const FOO);
+   |              ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:60:20
+   |
+LL | global_asm!("{1}", const FOO);
+   |                    ^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:63:14
+   |
+LL | global_asm!("{a}");
+   |              ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:65:14
+   |
+LL | global_asm!("{}", a = const FOO);
+   |              ^^   ------------- named argument
+   |              |
+   |              from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:68:14
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |              ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:68:20
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |                    ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:71:16
+   |
+LL | global_asm!("{:foo}", const FOO);
+   |                ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:73:17
+   |
+LL | global_asm!("", const FOO, const FOO);
+   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                 |
+   |                 argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: aborting due to 21 previous errors
+
diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..3b69186
--- /dev/null
@@ -0,0 +1,187 @@
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:31:15
+   |
+LL |         asm!("{}");
+   |               ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:33:15
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:33:21
+   |
+LL |         asm!("{1}", in(reg) foo);
+   |                     ^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:36:15
+   |
+LL |         asm!("{a}");
+   |               ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:38:15
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |               ^^   --------------- named argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:38:20
+   |
+LL |         asm!("{}", a = in(reg) foo);
+   |                    ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:41:15
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |               ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:41:21
+   |
+LL |         asm!("{1}", a = in(reg) foo);
+   |                     ^^^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:45:15
+   |
+LL |         asm!("{}", in("eax") foo);
+   |               ^^   ------------- explicit register argument
+   |               |
+   |               from here
+   |
+   = note: no positional arguments were given
+note: explicit register arguments cannot be used in the asm template
+  --> $DIR/bad-template.rs:45:20
+   |
+LL |         asm!("{}", in("eax") foo);
+   |                    ^^^^^^^^^^^^^
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:50:17
+   |
+LL |         asm!("{:foo}", in(reg) foo);
+   |                 ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:52:18
+   |
+LL |         asm!("", in(reg) 0, in(reg) 1);
+   |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                  |
+   |                  argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:58:14
+   |
+LL | global_asm!("{}");
+   |              ^^ from here
+   |
+   = note: no arguments were given
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:60:14
+   |
+LL | global_asm!("{1}", const FOO);
+   |              ^^^ from here
+   |
+   = note: there is 1 argument
+
+error: argument never used
+  --> $DIR/bad-template.rs:60:20
+   |
+LL | global_asm!("{1}", const FOO);
+   |                    ^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
+
+error: there is no argument named `a`
+  --> $DIR/bad-template.rs:63:14
+   |
+LL | global_asm!("{a}");
+   |              ^^^
+
+error: invalid reference to argument at index 0
+  --> $DIR/bad-template.rs:65:14
+   |
+LL | global_asm!("{}", a = const FOO);
+   |              ^^   ------------- named argument
+   |              |
+   |              from here
+   |
+   = note: no positional arguments were given
+note: named arguments cannot be referenced by position
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^
+
+error: named argument never used
+  --> $DIR/bad-template.rs:65:19
+   |
+LL | global_asm!("{}", a = const FOO);
+   |                   ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: invalid reference to argument at index 1
+  --> $DIR/bad-template.rs:68:14
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |              ^^^ from here
+   |
+   = note: no positional arguments were given
+
+error: named argument never used
+  --> $DIR/bad-template.rs:68:20
+   |
+LL | global_asm!("{1}", a = const FOO);
+   |                    ^^^^^^^^^^^^^ named argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
+
+error: asm template modifier must be a single character
+  --> $DIR/bad-template.rs:71:16
+   |
+LL | global_asm!("{:foo}", const FOO);
+   |                ^^^
+
+error: multiple unused asm arguments
+  --> $DIR/bad-template.rs:73:17
+   |
+LL | global_asm!("", const FOO, const FOO);
+   |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
+   |                 |
+   |                 argument never used
+   |
+   = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
+
+error: aborting due to 21 previous errors
+
diff --git a/src/test/ui/asm/const.rs b/src/test/ui/asm/const.rs
deleted file mode 100644 (file)
index d4de9ab..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// min-llvm-version: 10.0.1
-// only-x86_64
-// run-pass
-// revisions: mirunsafeck thirunsafeck
-// [thirunsafeck]compile-flags: -Z thir-unsafeck
-
-#![feature(asm, global_asm)]
-
-fn const_generic<const X: usize>() -> usize {
-    unsafe {
-        let a: usize;
-        asm!("mov {}, {}", out(reg) a, const X);
-        a
-    }
-}
-
-const fn constfn(x: usize) -> usize {
-    x
-}
-
-fn main() {
-    unsafe {
-        let a: usize;
-        asm!("mov {}, {}", out(reg) a, const 5);
-        assert_eq!(a, 5);
-
-        let b: usize;
-        asm!("mov {}, {}", out(reg) b, const constfn(5));
-        assert_eq!(b, 5);
-
-        let c: usize;
-        asm!("mov {}, {}", out(reg) c, const constfn(5) + constfn(5));
-        assert_eq!(c, 10);
-    }
-
-    let d = const_generic::<5>();
-    assert_eq!(d, 5);
-}
-
-global_asm!("mov eax, {}", const 5);
-global_asm!("mov eax, {}", const constfn(5));
-global_asm!("mov eax, {}", const constfn(5) + constfn(5));
diff --git a/src/test/ui/asm/duplicate-options.fixed b/src/test/ui/asm/duplicate-options.fixed
deleted file mode 100644 (file)
index d4444e9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// only-x86_64
-// run-rustfix
-
-#![feature(asm, global_asm)]
-
-fn main() {
-    unsafe {
-        asm!("", options(nomem, ));
-        //~^ ERROR the `nomem` option was already provided
-        asm!("", options(att_syntax, ));
-        //~^ ERROR the `att_syntax` option was already provided
-        asm!("", options(nostack, att_syntax), options());
-        //~^ ERROR the `nostack` option was already provided
-        asm!("", options(nostack, ), options(), options());
-        //~^ ERROR the `nostack` option was already provided
-        //~| ERROR the `nostack` option was already provided
-        //~| ERROR the `nostack` option was already provided
-        asm!(
-            "",
-            options(nomem, noreturn),
-            options(att_syntax, ), //~ ERROR the `noreturn` option was already provided
-            options( nostack), //~ ERROR the `nomem` option was already provided
-            options(), //~ ERROR the `noreturn` option was already provided
-        );
-    }
-}
-
-global_asm!("", options(att_syntax, ));
-//~^ ERROR the `att_syntax` option was already provided
diff --git a/src/test/ui/asm/duplicate-options.rs b/src/test/ui/asm/duplicate-options.rs
deleted file mode 100644 (file)
index fd28311..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// only-x86_64
-// run-rustfix
-
-#![feature(asm, global_asm)]
-
-fn main() {
-    unsafe {
-        asm!("", options(nomem, nomem));
-        //~^ ERROR the `nomem` option was already provided
-        asm!("", options(att_syntax, att_syntax));
-        //~^ ERROR the `att_syntax` option was already provided
-        asm!("", options(nostack, att_syntax), options(nostack));
-        //~^ ERROR the `nostack` option was already provided
-        asm!("", options(nostack, nostack), options(nostack), options(nostack));
-        //~^ ERROR the `nostack` option was already provided
-        //~| ERROR the `nostack` option was already provided
-        //~| ERROR the `nostack` option was already provided
-        asm!(
-            "",
-            options(nomem, noreturn),
-            options(att_syntax, noreturn), //~ ERROR the `noreturn` option was already provided
-            options(nomem, nostack), //~ ERROR the `nomem` option was already provided
-            options(noreturn), //~ ERROR the `noreturn` option was already provided
-        );
-    }
-}
-
-global_asm!("", options(att_syntax, att_syntax));
-//~^ ERROR the `att_syntax` option was already provided
diff --git a/src/test/ui/asm/duplicate-options.stderr b/src/test/ui/asm/duplicate-options.stderr
deleted file mode 100644 (file)
index 53edf8f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-error: the `nomem` option was already provided
-  --> $DIR/duplicate-options.rs:8:33
-   |
-LL |         asm!("", options(nomem, nomem));
-   |                                 ^^^^^ this option was already provided
-
-error: the `att_syntax` option was already provided
-  --> $DIR/duplicate-options.rs:10:38
-   |
-LL |         asm!("", options(att_syntax, att_syntax));
-   |                                      ^^^^^^^^^^ this option was already provided
-
-error: the `nostack` option was already provided
-  --> $DIR/duplicate-options.rs:12:56
-   |
-LL |         asm!("", options(nostack, att_syntax), options(nostack));
-   |                                                        ^^^^^^^ this option was already provided
-
-error: the `nostack` option was already provided
-  --> $DIR/duplicate-options.rs:14:35
-   |
-LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
-   |                                   ^^^^^^^ this option was already provided
-
-error: the `nostack` option was already provided
-  --> $DIR/duplicate-options.rs:14:53
-   |
-LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
-   |                                                     ^^^^^^^ this option was already provided
-
-error: the `nostack` option was already provided
-  --> $DIR/duplicate-options.rs:14:71
-   |
-LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
-   |                                                                       ^^^^^^^ this option was already provided
-
-error: the `noreturn` option was already provided
-  --> $DIR/duplicate-options.rs:21:33
-   |
-LL |             options(att_syntax, noreturn),
-   |                                 ^^^^^^^^ this option was already provided
-
-error: the `nomem` option was already provided
-  --> $DIR/duplicate-options.rs:22:21
-   |
-LL |             options(nomem, nostack),
-   |                     ^^^^^ this option was already provided
-
-error: the `noreturn` option was already provided
-  --> $DIR/duplicate-options.rs:23:21
-   |
-LL |             options(noreturn),
-   |                     ^^^^^^^^ this option was already provided
-
-error: the `att_syntax` option was already provided
-  --> $DIR/duplicate-options.rs:28:37
-   |
-LL | global_asm!("", options(att_syntax, att_syntax));
-   |                                     ^^^^^^^^^^ this option was already provided
-
-error: aborting due to 10 previous errors
-
diff --git a/src/test/ui/asm/interpolated-idents.rs b/src/test/ui/asm/interpolated-idents.rs
deleted file mode 100644 (file)
index f4cb749..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// only-x86_64
-
-#![feature(asm)]
-
-macro_rules! m {
-    ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
-     $pure:ident $nomem:ident $readonly:ident $preserves_flags:ident
-     $noreturn:ident $nostack:ident $att_syntax:ident $options:ident) => {
-        unsafe {
-            asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
-            //~^ ERROR asm outputs are not allowed with the `noreturn` option
-            const x, sym x,
-            $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
-            //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
-            //~| ERROR the `pure` and `noreturn` options are mutually exclusive
-        }
-    };
-}
-
-fn main() {
-    m!(in out lateout inout inlateout const sym
-       pure nomem readonly preserves_flags
-       noreturn nostack att_syntax options);
-}
diff --git a/src/test/ui/asm/interpolated-idents.stderr b/src/test/ui/asm/interpolated-idents.stderr
deleted file mode 100644 (file)
index 5de8d20..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-error: the `nomem` and `readonly` options are mutually exclusive
-  --> $DIR/interpolated-idents.rs:13:13
-   |
-LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | /     m!(in out lateout inout inlateout const sym
-LL | |        pure nomem readonly preserves_flags
-LL | |        noreturn nostack att_syntax options);
-   | |____________________________________________- in this macro invocation
-   |
-   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: the `pure` and `noreturn` options are mutually exclusive
-  --> $DIR/interpolated-idents.rs:13:13
-   |
-LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | /     m!(in out lateout inout inlateout const sym
-LL | |        pure nomem readonly preserves_flags
-LL | |        noreturn nostack att_syntax options);
-   | |____________________________________________- in this macro invocation
-   |
-   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: asm outputs are not allowed with the `noreturn` option
-  --> $DIR/interpolated-idents.rs:10:32
-   |
-LL |               asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
-   |                                  ^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^^^^^^^^
-...
-LL |       m!(in out lateout inout inlateout const sym
-   |  _____-
-   | |_____|
-   | |_____|
-   | |_____|
-   | |
-LL | |        pure nomem readonly preserves_flags
-LL | |        noreturn nostack att_syntax options);
-   | |                                            -
-   | |____________________________________________|
-   | |____________________________________________in this macro invocation
-   | |____________________________________________in this macro invocation
-   | |____________________________________________in this macro invocation
-   |                                              in this macro invocation
-   |
-   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 3 previous errors
-
index 678534657cb31982643303eab649f2ad853a8647..960f7427e3405c3b810e8dda9233a39c1b735fba 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Zsave-analysis
-// only-x86_64
+// needs-asm-support
 // Also test for #72960
 
 #![feature(asm)]
diff --git a/src/test/ui/asm/issue-82869.rs b/src/test/ui/asm/issue-82869.rs
deleted file mode 100644 (file)
index a8e688c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// only-x86_64
-// Make sure rustc doesn't ICE on asm! for a foreign architecture.
-
-#![feature(asm)]
-#![crate_type = "rlib"]
-
-pub unsafe fn aarch64(a: f64, b: f64) -> f64 {
-    let c;
-    asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
-        || {};
-        b
-    });
-    //~^^^^ invalid register class
-    //~^^^^^ invalid register class
-    //~^^^^^^ invalid register
-    c
-}
-
-pub unsafe fn x86(a: f64, b: f64) -> f64 {
-    let c;
-    asm!("addsd {}, {}, xmm0", out(xmm_reg) c, in(xmm_reg) a, in("xmm0") b);
-    c
-}
diff --git a/src/test/ui/asm/issue-82869.stderr b/src/test/ui/asm/issue-82869.stderr
deleted file mode 100644 (file)
index d05714e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-error: invalid register class `vreg`: unknown register class
-  --> $DIR/issue-82869.rs:9:32
-   |
-LL |     asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
-   |                                ^^^^^^^^^^^
-
-error: invalid register class `vreg`: unknown register class
-  --> $DIR/issue-82869.rs:9:45
-   |
-LL |     asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
-   |                                             ^^^^^^^^^^
-
-error: invalid register `d0`: unknown register
-  --> $DIR/issue-82869.rs:9:57
-   |
-LL |       asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
-   |  _________________________________________________________^
-LL | |         || {};
-LL | |         b
-LL | |     });
-   | |_____^
-
-error: aborting due to 3 previous errors
-
index b1fc13b6a7e8cfac6141b0c9eebf25e99ad36de9..5b6453c42c6eb950e71d21853b01d3c7db5b8e27 100644 (file)
@@ -1,4 +1,7 @@
-// only-x86_64
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
 // Make sure rustc doesn't ICE on asm! when output type is !.
 
 #![feature(asm)]
index 1eb72b68a7f044bd266a061ad8c83998acf2396b..de3e28fdd12289281101d64550b28171fd6c9f36 100644 (file)
@@ -1,5 +1,5 @@
 error: cannot use value of type `!` for inline assembly
-  --> $DIR/issue-87802.rs:9:36
+  --> $DIR/issue-87802.rs:12:36
    |
 LL |         asm!("/* {0} */", out(reg) x);
    |                                    ^
index 5b2a8ed3034a6cffe1714af6c75902063079cece..f6725605b924b5fb71b05c0b510f7c79cc555126 100644 (file)
@@ -1,5 +1,5 @@
 // check-pass
-// only-x86_64
+// needs-asm-support
 #![feature(asm)]
 #![feature(naked_functions)]
 #![crate_type = "lib"]
diff --git a/src/test/ui/asm/naked-functions-unused.aarch64.stderr b/src/test/ui/asm/naked-functions-unused.aarch64.stderr
new file mode 100644 (file)
index 0000000..a898ab1
--- /dev/null
@@ -0,0 +1,69 @@
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:15:32
+   |
+LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
+   |                                ^ help: if this is intentional, prefix it with an underscore: `_a`
+   |
+note: the lint level is defined here
+  --> $DIR/naked-functions-unused.rs:4:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:15:42
+   |
+LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
+   |                                          ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:24:38
+   |
+LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
+   |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:24:48
+   |
+LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
+   |                                                ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:30:41
+   |
+LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
+   |                                         ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:30:51
+   |
+LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
+   |                                                   ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:38:40
+   |
+LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
+   |                                        ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:38:50
+   |
+LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
+   |                                                  ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:44:43
+   |
+LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
+   |                                           ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:44:53
+   |
+LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
+   |                                                     ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: aborting due to 10 previous errors
+
index e1f2362bb6fd075f2d3f8a0fa6c6d496485227be..4c5c2ac1c197e3685ed071566e3bc7c2767f2ca4 100644 (file)
@@ -1,16 +1,18 @@
-// only-x86_64
+// revisions: x86_64 aarch64
+//[x86_64] only-x86_64
+//[aarch64] only-aarch64
 #![deny(unused)]
 #![feature(asm)]
 #![feature(naked_functions)]
 #![crate_type = "lib"]
 
 pub trait Trait {
-    extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize;
-    extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize;
+    extern "C" fn trait_associated(a: usize, b: usize) -> usize;
+    extern "C" fn trait_method(&self, a: usize, b: usize) -> usize;
 }
 
 pub mod normal {
-    pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
+    pub extern "C" fn function(a: usize, b: usize) -> usize {
         //~^ ERROR unused variable: `a`
         //~| ERROR unused variable: `b`
         unsafe { asm!("", options(noreturn)); }
@@ -19,13 +21,13 @@ pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
     pub struct Normal;
 
     impl Normal {
-        pub extern "sysv64" fn associated(a: usize, b: usize) -> usize {
+        pub extern "C" fn associated(a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
             unsafe { asm!("", options(noreturn)); }
         }
 
-        pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize {
+        pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
             unsafe { asm!("", options(noreturn)); }
@@ -33,13 +35,13 @@ pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize {
     }
 
     impl super::Trait for Normal {
-        extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize {
+        extern "C" fn trait_associated(a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
             unsafe { asm!("", options(noreturn)); }
         }
 
-        extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize {
+        extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
             unsafe { asm!("", options(noreturn)); }
@@ -49,7 +51,7 @@ extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize {
 
 pub mod naked {
     #[naked]
-    pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
+    pub extern "C" fn function(a: usize, b: usize) -> usize {
         unsafe { asm!("", options(noreturn)); }
     }
 
@@ -57,24 +59,24 @@ pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
 
     impl Naked {
         #[naked]
-        pub extern "sysv64" fn associated(a: usize, b: usize) -> usize {
+        pub extern "C" fn associated(a: usize, b: usize) -> usize {
             unsafe { asm!("", options(noreturn)); }
         }
 
         #[naked]
-        pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize {
+        pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
             unsafe { asm!("", options(noreturn)); }
         }
     }
 
     impl super::Trait for Naked {
         #[naked]
-        extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize {
+        extern "C" fn trait_associated(a: usize, b: usize) -> usize {
             unsafe { asm!("", options(noreturn)); }
         }
 
         #[naked]
-        extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize {
+        extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
             unsafe { asm!("", options(noreturn)); }
         }
     }
diff --git a/src/test/ui/asm/naked-functions-unused.stderr b/src/test/ui/asm/naked-functions-unused.stderr
deleted file mode 100644 (file)
index 8403533..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:13:37
-   |
-LL |     pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
-   |                                     ^ help: if this is intentional, prefix it with an underscore: `_a`
-   |
-note: the lint level is defined here
-  --> $DIR/naked-functions-unused.rs:2:9
-   |
-LL | #![deny(unused)]
-   |         ^^^^^^
-   = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
-
-error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:13:47
-   |
-LL |     pub extern "sysv64" fn function(a: usize, b: usize) -> usize {
-   |                                               ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:22:43
-   |
-LL |         pub extern "sysv64" fn associated(a: usize, b: usize) -> usize {
-   |                                           ^ help: if this is intentional, prefix it with an underscore: `_a`
-
-error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:22:53
-   |
-LL |         pub extern "sysv64" fn associated(a: usize, b: usize) -> usize {
-   |                                                     ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:28:46
-   |
-LL |         pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize {
-   |                                              ^ help: if this is intentional, prefix it with an underscore: `_a`
-
-error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:28:56
-   |
-LL |         pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize {
-   |                                                        ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:36:45
-   |
-LL |         extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize {
-   |                                             ^ help: if this is intentional, prefix it with an underscore: `_a`
-
-error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:36:55
-   |
-LL |         extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize {
-   |                                                       ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:42:48
-   |
-LL |         extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize {
-   |                                                ^ help: if this is intentional, prefix it with an underscore: `_a`
-
-error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:42:58
-   |
-LL |         extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize {
-   |                                                          ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: aborting due to 10 previous errors
-
diff --git a/src/test/ui/asm/naked-functions-unused.x86_64.stderr b/src/test/ui/asm/naked-functions-unused.x86_64.stderr
new file mode 100644 (file)
index 0000000..a898ab1
--- /dev/null
@@ -0,0 +1,69 @@
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:15:32
+   |
+LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
+   |                                ^ help: if this is intentional, prefix it with an underscore: `_a`
+   |
+note: the lint level is defined here
+  --> $DIR/naked-functions-unused.rs:4:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:15:42
+   |
+LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
+   |                                          ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:24:38
+   |
+LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
+   |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:24:48
+   |
+LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
+   |                                                ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:30:41
+   |
+LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
+   |                                         ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:30:51
+   |
+LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
+   |                                                   ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:38:40
+   |
+LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
+   |                                        ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:38:50
+   |
+LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
+   |                                                  ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/naked-functions-unused.rs:44:43
+   |
+LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
+   |                                           ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/naked-functions-unused.rs:44:53
+   |
+LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
+   |                                                     ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: aborting due to 10 previous errors
+
index 72918a1411755874a8bd2d63a2f03dba9bb0227c..803311d4235058a0a6419f2c44a5a4f94b1692da 100644 (file)
@@ -1,4 +1,8 @@
-// only-x86_64
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
+
 #![feature(asm)]
 #![feature(llvm_asm)]
 #![feature(naked_functions)]
index 3b54757cfe8184af3a154205532bba41b983b2a3..46ceef032427c97487be328b48bcd83f1c5d1ef4 100644 (file)
@@ -1,35 +1,35 @@
 error: asm with the `pure` option must have at least one output
-  --> $DIR/naked-functions.rs:127:14
+  --> $DIR/naked-functions.rs:131:14
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:14:5
+  --> $DIR/naked-functions.rs:18:5
    |
 LL |     mut a: u32,
    |     ^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:16:5
+  --> $DIR/naked-functions.rs:20:5
    |
 LL |     &b: &i32,
    |     ^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:18:6
+  --> $DIR/naked-functions.rs:22:6
    |
 LL |     (None | Some(_)): Option<std::ptr::NonNull<u8>>,
    |      ^^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:20:5
+  --> $DIR/naked-functions.rs:24:5
    |
 LL |     P { x, y }: P,
    |     ^^^^^^^^^^
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:30:5
+  --> $DIR/naked-functions.rs:34:5
    |
 LL |     a + 1
    |     ^
@@ -37,7 +37,7 @@ LL |     a + 1
    = help: follow the calling convention in asm block to use parameters
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:27:1
+  --> $DIR/naked-functions.rs:31:1
    |
 LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 {
 LL | |
@@ -53,7 +53,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:36:31
+  --> $DIR/naked-functions.rs:40:31
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                               ^
@@ -61,7 +61,7 @@ LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    = help: follow the calling convention in asm block to use parameters
 
 warning: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:36:23
+  --> $DIR/naked-functions.rs:40:23
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                       ^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:43:1
+  --> $DIR/naked-functions.rs:47:1
    |
 LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
 LL | |
@@ -84,7 +84,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:63:10
+  --> $DIR/naked-functions.rs:67:10
    |
 LL |          in(reg) a,
    |          ^^^^^^^^^
@@ -102,7 +102,7 @@ LL |          out(reg) e,
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:60:5
+  --> $DIR/naked-functions.rs:64:5
    |
 LL | /     asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
 LL | |
@@ -117,7 +117,7 @@ LL | |     );
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:50:1
+  --> $DIR/naked-functions.rs:54:1
    |
 LL | / pub unsafe extern "C" fn unsupported_operands() {
 LL | |
@@ -141,7 +141,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:76:1
+  --> $DIR/naked-functions.rs:80:1
    |
 LL | / pub extern "C" fn missing_assembly() {
 LL | |
@@ -153,7 +153,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:85:5
+  --> $DIR/naked-functions.rs:89:5
    |
 LL |     asm!("");
    |     ^^^^^^^^^
@@ -162,7 +162,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:88:5
+  --> $DIR/naked-functions.rs:92:5
    |
 LL |     asm!("");
    |     ^^^^^^^^^
@@ -171,7 +171,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:91:5
+  --> $DIR/naked-functions.rs:95:5
    |
 LL |     asm!("");
    |     ^^^^^^^^^
@@ -180,7 +180,7 @@ LL |     asm!("");
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:82:1
+  --> $DIR/naked-functions.rs:86:1
    |
 LL | / pub extern "C" fn too_many_asm_blocks() {
 LL | |
@@ -202,7 +202,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:102:11
+  --> $DIR/naked-functions.rs:106:11
    |
 LL |         *&y
    |           ^
@@ -210,7 +210,7 @@ LL |         *&y
    = help: follow the calling convention in asm block to use parameters
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:99:5
+  --> $DIR/naked-functions.rs:103:5
    |
 LL | /     pub extern "C" fn inner(y: usize) -> usize {
 LL | |
@@ -225,7 +225,7 @@ LL | |     }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: the LLVM-style inline assembly is unsupported in naked functions
-  --> $DIR/naked-functions.rs:112:5
+  --> $DIR/naked-functions.rs:116:5
    |
 LL |     llvm_asm!("");
    |     ^^^^^^^^^^^^^^
@@ -236,7 +236,7 @@ LL |     llvm_asm!("");
    = note: this warning originates in the macro `llvm_asm` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:109:1
+  --> $DIR/naked-functions.rs:113:1
    |
 LL | / unsafe extern "C" fn llvm() -> ! {
 LL | |
@@ -252,7 +252,7 @@ LL | | }
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm options unsupported in naked functions: `nomem`, `preserves_flags`
-  --> $DIR/naked-functions.rs:120:5
+  --> $DIR/naked-functions.rs:124:5
    |
 LL |     asm!("", options(nomem, preserves_flags, noreturn));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +261,7 @@ LL |     asm!("", options(nomem, preserves_flags, noreturn));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
-  --> $DIR/naked-functions.rs:127:5
+  --> $DIR/naked-functions.rs:131:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -270,7 +270,7 @@ LL |     asm!("", options(readonly, nostack), options(pure));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:127:5
+  --> $DIR/naked-functions.rs:131:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |     asm!("", options(readonly, nostack), options(pure));
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:136:15
+  --> $DIR/naked-functions.rs:140:15
    |
 LL | pub unsafe fn default_abi() {
    |               ^^^^^^^^^^^
@@ -287,13 +287,13 @@ LL | pub unsafe fn default_abi() {
    = note: `#[warn(undefined_naked_function_abi)]` on by default
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:142:29
+  --> $DIR/naked-functions.rs:146:29
    |
 LL | pub unsafe extern "Rust" fn rust_abi() {
    |                             ^^^^^^^^
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:176:1
+  --> $DIR/naked-functions.rs:180:1
    |
 LL | #[inline]
    | ^^^^^^^^^
@@ -302,7 +302,7 @@ LL | #[inline]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:184:1
+  --> $DIR/naked-functions.rs:188:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | #[inline(always)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:192:1
+  --> $DIR/naked-functions.rs:196:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
@@ -320,7 +320,7 @@ LL | #[inline(never)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:200:1
+  --> $DIR/naked-functions.rs:204:1
    |
 LL | #[inline]
    | ^^^^^^^^^
@@ -329,7 +329,7 @@ LL | #[inline]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:203:1
+  --> $DIR/naked-functions.rs:207:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
@@ -338,7 +338,7 @@ LL | #[inline(always)]
    = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
 
 warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:206:1
+  --> $DIR/naked-functions.rs:210:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
index 9f487bd8061fc5994d3c7cfed36dcaf91f3dcce0..82c47945a7b302c4db11ee389e3c54877b98a46c 100644 (file)
@@ -1,4 +1,7 @@
-// only-x86_64
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
 
 // Tests that the use of named labels in the `asm!` macro are linted against
 // except for in `#[naked]` fns.
@@ -99,9 +102,6 @@ fn main() {
         asm!("\x41\x42\x43\x3A\x20\x6E\x6F\x70"); //~ ERROR avoid using named labels
 
         // Non-label colons - should pass
-        // (most of these are stolen from other places)
-        asm!("{:l}", in(reg) 0i64);
-        asm!("{:e}", in(reg) 0f32);
         asm!("mov rax, qword ptr fs:[0]");
 
         // Comments
index 396f0a1942428800f0e711f817b4332f941da732..75c848cdc572d37a64b92122b904dbd303b65f94 100644 (file)
@@ -1,5 +1,5 @@
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:19:15
+  --> $DIR/named-asm-labels.rs:22:15
    |
 LL |         asm!("bar: nop");
    |               ^^^
@@ -9,7 +9,7 @@ LL |         asm!("bar: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:22:15
+  --> $DIR/named-asm-labels.rs:25:15
    |
 LL |         asm!("abcd:");
    |               ^^^^
@@ -18,7 +18,7 @@ LL |         asm!("abcd:");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:25:15
+  --> $DIR/named-asm-labels.rs:28:15
    |
 LL |         asm!("foo: bar1: nop");
    |               ^^^  ^^^^
@@ -27,7 +27,7 @@ LL |         asm!("foo: bar1: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:29:15
+  --> $DIR/named-asm-labels.rs:32:15
    |
 LL |         asm!("foo1: nop", "nop");
    |               ^^^^
@@ -36,7 +36,7 @@ LL |         asm!("foo1: nop", "nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:30:15
+  --> $DIR/named-asm-labels.rs:33:15
    |
 LL |         asm!("foo2: foo3: nop", "nop");
    |               ^^^^  ^^^^
@@ -45,7 +45,7 @@ LL |         asm!("foo2: foo3: nop", "nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:32:22
+  --> $DIR/named-asm-labels.rs:35:22
    |
 LL |         asm!("nop", "foo4: nop");
    |                      ^^^^
@@ -54,7 +54,7 @@ LL |         asm!("nop", "foo4: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:33:15
+  --> $DIR/named-asm-labels.rs:36:15
    |
 LL |         asm!("foo5: nop", "foo6: nop");
    |               ^^^^
@@ -63,7 +63,7 @@ LL |         asm!("foo5: nop", "foo6: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:33:28
+  --> $DIR/named-asm-labels.rs:36:28
    |
 LL |         asm!("foo5: nop", "foo6: nop");
    |                            ^^^^
@@ -72,7 +72,7 @@ LL |         asm!("foo5: nop", "foo6: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:38:15
+  --> $DIR/named-asm-labels.rs:41:15
    |
 LL |         asm!("foo7: nop; foo8: nop");
    |               ^^^^       ^^^^
@@ -81,7 +81,7 @@ LL |         asm!("foo7: nop; foo8: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:40:15
+  --> $DIR/named-asm-labels.rs:43:15
    |
 LL |         asm!("foo9: nop; nop");
    |               ^^^^
@@ -90,7 +90,7 @@ LL |         asm!("foo9: nop; nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:41:20
+  --> $DIR/named-asm-labels.rs:44:20
    |
 LL |         asm!("nop; foo10: nop");
    |                    ^^^^^
@@ -99,7 +99,7 @@ LL |         asm!("nop; foo10: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:44:15
+  --> $DIR/named-asm-labels.rs:47:15
    |
 LL |         asm!("bar2: nop\n bar3: nop");
    |               ^^^^        ^^^^
@@ -108,7 +108,7 @@ LL |         asm!("bar2: nop\n bar3: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:46:15
+  --> $DIR/named-asm-labels.rs:49:15
    |
 LL |         asm!("bar4: nop\n nop");
    |               ^^^^
@@ -117,7 +117,7 @@ LL |         asm!("bar4: nop\n nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:47:21
+  --> $DIR/named-asm-labels.rs:50:21
    |
 LL |         asm!("nop\n bar5: nop");
    |                     ^^^^
@@ -126,7 +126,7 @@ LL |         asm!("nop\n bar5: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:48:21
+  --> $DIR/named-asm-labels.rs:51:21
    |
 LL |         asm!("nop\n bar6: bar7: nop");
    |                     ^^^^  ^^^^
@@ -135,7 +135,7 @@ LL |         asm!("nop\n bar6: bar7: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:54:13
+  --> $DIR/named-asm-labels.rs:57:13
    |
 LL |             blah2: nop
    |             ^^^^^
@@ -146,7 +146,7 @@ LL |             blah3: nop
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:63:19
+  --> $DIR/named-asm-labels.rs:66:19
    |
 LL |             nop ; blah4: nop
    |                   ^^^^^
@@ -155,7 +155,7 @@ LL |             nop ; blah4: nop
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:77:15
+  --> $DIR/named-asm-labels.rs:80:15
    |
 LL |         asm!("blah1: 2bar: nop");
    |               ^^^^^
@@ -164,7 +164,7 @@ LL |         asm!("blah1: 2bar: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:80:15
+  --> $DIR/named-asm-labels.rs:83:15
    |
 LL |         asm!("def: def: nop");
    |               ^^^
@@ -173,7 +173,7 @@ LL |         asm!("def: def: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:81:15
+  --> $DIR/named-asm-labels.rs:84:15
    |
 LL |         asm!("def: nop\ndef: nop");
    |               ^^^
@@ -182,7 +182,7 @@ LL |         asm!("def: nop\ndef: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:82:15
+  --> $DIR/named-asm-labels.rs:85:15
    |
 LL |         asm!("def: nop; def: nop");
    |               ^^^
@@ -191,7 +191,7 @@ LL |         asm!("def: nop; def: nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:90:15
+  --> $DIR/named-asm-labels.rs:93:15
    |
 LL |         asm!("fooo\u{003A} nop");
    |               ^^^^^^^^^^^^^^^^
@@ -200,7 +200,7 @@ LL |         asm!("fooo\u{003A} nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:91:15
+  --> $DIR/named-asm-labels.rs:94:15
    |
 LL |         asm!("foooo\x3A nop");
    |               ^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |         asm!("foooo\x3A nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:94:15
+  --> $DIR/named-asm-labels.rs:97:15
    |
 LL |         asm!("fooooo:\u{000A} nop");
    |               ^^^^^^
@@ -218,7 +218,7 @@ LL |         asm!("fooooo:\u{000A} nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:95:15
+  --> $DIR/named-asm-labels.rs:98:15
    |
 LL |         asm!("foooooo:\x0A nop");
    |               ^^^^^^^
@@ -227,7 +227,7 @@ LL |         asm!("foooooo:\x0A nop");
    = note: see the asm section of the unstable book <https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:99:14
+  --> $DIR/named-asm-labels.rs:102:14
    |
 LL |         asm!("\x41\x42\x43\x3A\x20\x6E\x6F\x70");
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 5e1ee93bfb0735320c3266feaa9b0a4fa0d30034..cb92ff0ad1d6d863aa2dc17d6852dd8c4d4aa262 100644 (file)
@@ -1,4 +1,4 @@
-// only-x86_64
+// needs-asm-support
 // check-pass
 
 #![feature(asm, never_type)]
diff --git a/src/test/ui/asm/parse-error.rs b/src/test/ui/asm/parse-error.rs
deleted file mode 100644 (file)
index fa14c52..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// only-x86_64
-
-#![feature(asm, global_asm)]
-
-fn main() {
-    let mut foo = 0;
-    let mut bar = 0;
-    unsafe {
-        asm!();
-        //~^ ERROR requires at least a template string argument
-        asm!(foo);
-        //~^ ERROR asm template must be a string literal
-        asm!("{}" foo);
-        //~^ ERROR expected token: `,`
-        asm!("{}", foo);
-        //~^ ERROR expected operand, clobber_abi, options, or additional template string
-        asm!("{}", in foo);
-        //~^ ERROR expected `(`, found `foo`
-        asm!("{}", in(reg foo));
-        //~^ ERROR expected `)`, found `foo`
-        asm!("{}", in(reg));
-        //~^ ERROR expected expression, found end of macro arguments
-        asm!("{}", inout(=) foo => bar);
-        //~^ ERROR expected register class or explicit register
-        asm!("{}", inout(reg) foo =>);
-        //~^ ERROR expected expression, found end of macro arguments
-        asm!("{}", in(reg) foo => bar);
-        //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
-        asm!("{}", sym foo + bar);
-        //~^ ERROR argument to `sym` must be a path expression
-        asm!("", options(foo));
-        //~^ ERROR expected one of
-        asm!("", options(nomem foo));
-        //~^ ERROR expected one of
-        asm!("", options(nomem, foo));
-        //~^ ERROR expected one of
-        asm!("{}", options(), const foo);
-        //~^ ERROR arguments are not allowed after options
-        //~^^ ERROR attempt to use a non-constant value in a constant
-        asm!("", clobber_abi(foo));
-        //~^ ERROR expected string literal
-        asm!("", clobber_abi("C" foo));
-        //~^ ERROR expected `)`, found `foo`
-        asm!("", clobber_abi("C", foo));
-        //~^ ERROR expected `)`, found `,`
-        asm!("{}", clobber_abi("C"), const foo);
-        //~^ ERROR arguments are not allowed after clobber_abi
-        //~^^ ERROR attempt to use a non-constant value in a constant
-        asm!("", options(), clobber_abi("C"));
-        //~^ ERROR clobber_abi is not allowed after options
-        asm!("{}", options(), clobber_abi("C"), const foo);
-        //~^ ERROR clobber_abi is not allowed after options
-        asm!("", clobber_abi("C"), clobber_abi("C"));
-        //~^ ERROR clobber_abi specified multiple times
-        asm!("{a}", a = const foo, a = const bar);
-        //~^ ERROR duplicate argument named `a`
-        //~^^ ERROR argument never used
-        //~^^^ ERROR attempt to use a non-constant value in a constant
-        //~^^^^ ERROR attempt to use a non-constant value in a constant
-        asm!("", a = in("eax") foo);
-        //~^ ERROR explicit register arguments cannot have names
-        asm!("{a}", in("eax") foo, a = const bar);
-        //~^ ERROR named arguments cannot follow explicit register arguments
-        //~^^ ERROR attempt to use a non-constant value in a constant
-        asm!("{a}", in("eax") foo, a = const bar);
-        //~^ ERROR named arguments cannot follow explicit register arguments
-        //~^^ ERROR attempt to use a non-constant value in a constant
-        asm!("{1}", in("eax") foo, const bar);
-        //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
-        //~^^ ERROR attempt to use a non-constant value in a constant
-        asm!("", options(), "");
-        //~^ ERROR expected one of
-        asm!("{}", in(reg) foo, "{}", out(reg) foo);
-        //~^ ERROR expected one of
-        asm!(format!("{{{}}}", 0), in(reg) foo);
-        //~^ ERROR asm template must be a string literal
-        asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
-        //~^ ERROR asm template must be a string literal
-        asm!("{}", in(reg) _);
-        //~^ ERROR _ cannot be used for input operands
-        asm!("{}", inout(reg) _);
-        //~^ ERROR _ cannot be used for input operands
-        asm!("{}", inlateout(reg) _);
-        //~^ ERROR _ cannot be used for input operands
-    }
-}
-
-const FOO: i32 = 1;
-const BAR: i32 = 2;
-global_asm!();
-//~^ ERROR requires at least a template string argument
-global_asm!(FOO);
-//~^ ERROR asm template must be a string literal
-global_asm!("{}" FOO);
-//~^ ERROR expected token: `,`
-global_asm!("{}", FOO);
-//~^ ERROR expected operand, options, or additional template string
-global_asm!("{}", const);
-//~^ ERROR expected expression, found end of macro arguments
-global_asm!("{}", const(reg) FOO);
-//~^ ERROR expected one of
-global_asm!("", options(FOO));
-//~^ ERROR expected one of
-global_asm!("", options(nomem FOO));
-//~^ ERROR expected one of
-global_asm!("", options(nomem, FOO));
-//~^ ERROR expected one of
-global_asm!("{}", options(), const FOO);
-//~^ ERROR arguments are not allowed after options
-global_asm!("", clobber_abi(FOO));
-//~^ ERROR expected string literal
-global_asm!("", clobber_abi("C" FOO));
-//~^ ERROR expected `)`, found `FOO`
-global_asm!("", clobber_abi("C", FOO));
-//~^ ERROR expected `)`, found `,`
-global_asm!("{}", clobber_abi("C"), const FOO);
-//~^ ERROR arguments are not allowed after clobber_abi
-//~^^ ERROR `clobber_abi` cannot be used with `global_asm!`
-global_asm!("", options(), clobber_abi("C"));
-//~^ ERROR clobber_abi is not allowed after options
-global_asm!("{}", options(), clobber_abi("C"), const FOO);
-//~^ ERROR clobber_abi is not allowed after options
-global_asm!("", clobber_abi("C"), clobber_abi("C"));
-//~^ ERROR clobber_abi specified multiple times
-global_asm!("{a}", a = const FOO, a = const BAR);
-//~^ ERROR duplicate argument named `a`
-//~^^ ERROR argument never used
-global_asm!("", options(), "");
-//~^ ERROR expected one of
-global_asm!("{}", const FOO, "{}", const FOO);
-//~^ ERROR expected one of
-global_asm!(format!("{{{}}}", 0), const FOO);
-//~^ ERROR asm template must be a string literal
-global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
-//~^ ERROR asm template must be a string literal
diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr
deleted file mode 100644 (file)
index 78d342c..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-error: requires at least a template string argument
-  --> $DIR/parse-error.rs:9:9
-   |
-LL |         asm!();
-   |         ^^^^^^^
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:11:14
-   |
-LL |         asm!(foo);
-   |              ^^^
-
-error: expected token: `,`
-  --> $DIR/parse-error.rs:13:19
-   |
-LL |         asm!("{}" foo);
-   |                   ^^^ expected `,`
-
-error: expected operand, clobber_abi, options, or additional template string
-  --> $DIR/parse-error.rs:15:20
-   |
-LL |         asm!("{}", foo);
-   |                    ^^^ expected operand, clobber_abi, options, or additional template string
-
-error: expected `(`, found `foo`
-  --> $DIR/parse-error.rs:17:23
-   |
-LL |         asm!("{}", in foo);
-   |                       ^^^ expected `(`
-
-error: expected `)`, found `foo`
-  --> $DIR/parse-error.rs:19:27
-   |
-LL |         asm!("{}", in(reg foo));
-   |                           ^^^ expected `)`
-
-error: expected expression, found end of macro arguments
-  --> $DIR/parse-error.rs:21:27
-   |
-LL |         asm!("{}", in(reg));
-   |                           ^ expected expression
-
-error: expected register class or explicit register
-  --> $DIR/parse-error.rs:23:26
-   |
-LL |         asm!("{}", inout(=) foo => bar);
-   |                          ^
-
-error: expected expression, found end of macro arguments
-  --> $DIR/parse-error.rs:25:37
-   |
-LL |         asm!("{}", inout(reg) foo =>);
-   |                                     ^ expected expression
-
-error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
-  --> $DIR/parse-error.rs:27:32
-   |
-LL |         asm!("{}", in(reg) foo => bar);
-   |                                ^^ expected one of 7 possible tokens
-
-error: argument to `sym` must be a path expression
-  --> $DIR/parse-error.rs:29:24
-   |
-LL |         asm!("{}", sym foo + bar);
-   |                        ^^^^^^^^^
-
-error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
-  --> $DIR/parse-error.rs:31:26
-   |
-LL |         asm!("", options(foo));
-   |                          ^^^ expected one of 9 possible tokens
-
-error: expected one of `)` or `,`, found `foo`
-  --> $DIR/parse-error.rs:33:32
-   |
-LL |         asm!("", options(nomem foo));
-   |                                ^^^ expected one of `)` or `,`
-
-error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
-  --> $DIR/parse-error.rs:35:33
-   |
-LL |         asm!("", options(nomem, foo));
-   |                                 ^^^ expected one of 9 possible tokens
-
-error: arguments are not allowed after options
-  --> $DIR/parse-error.rs:37:31
-   |
-LL |         asm!("{}", options(), const foo);
-   |                    ---------  ^^^^^^^^^ argument
-   |                    |
-   |                    previous options
-
-error: expected string literal
-  --> $DIR/parse-error.rs:40:30
-   |
-LL |         asm!("", clobber_abi(foo));
-   |                              ^^^ not a string literal
-
-error: expected `)`, found `foo`
-  --> $DIR/parse-error.rs:42:34
-   |
-LL |         asm!("", clobber_abi("C" foo));
-   |                                  ^^^ expected `)`
-
-error: expected `)`, found `,`
-  --> $DIR/parse-error.rs:44:33
-   |
-LL |         asm!("", clobber_abi("C", foo));
-   |                                 ^ expected `)`
-
-error: arguments are not allowed after clobber_abi
-  --> $DIR/parse-error.rs:46:38
-   |
-LL |         asm!("{}", clobber_abi("C"), const foo);
-   |                    ----------------  ^^^^^^^^^ argument
-   |                    |
-   |                    clobber_abi
-
-error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:49:29
-   |
-LL |         asm!("", options(), clobber_abi("C"));
-   |                  ---------  ^^^^^^^^^^^^^^^^
-   |                  |
-   |                  options
-
-error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:51:31
-   |
-LL |         asm!("{}", options(), clobber_abi("C"), const foo);
-   |                    ---------  ^^^^^^^^^^^^^^^^
-   |                    |
-   |                    options
-
-error: clobber_abi specified multiple times
-  --> $DIR/parse-error.rs:53:36
-   |
-LL |         asm!("", clobber_abi("C"), clobber_abi("C"));
-   |                  ----------------  ^^^^^^^^^^^^^^^^
-   |                  |
-   |                  clobber_abi previously specified here
-
-error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:55:36
-   |
-LL |         asm!("{a}", a = const foo, a = const bar);
-   |                     -------------  ^^^^^^^^^^^^^ duplicate argument
-   |                     |
-   |                     previously here
-
-error: argument never used
-  --> $DIR/parse-error.rs:55:36
-   |
-LL |         asm!("{a}", a = const foo, a = const bar);
-   |                                    ^^^^^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
-
-error: explicit register arguments cannot have names
-  --> $DIR/parse-error.rs:60:18
-   |
-LL |         asm!("", a = in("eax") foo);
-   |                  ^^^^^^^^^^^^^^^^^
-
-error: named arguments cannot follow explicit register arguments
-  --> $DIR/parse-error.rs:62:36
-   |
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                     -------------  ^^^^^^^^^^^^^ named argument
-   |                     |
-   |                     explicit register argument
-
-error: named arguments cannot follow explicit register arguments
-  --> $DIR/parse-error.rs:65:36
-   |
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                     -------------  ^^^^^^^^^^^^^ named argument
-   |                     |
-   |                     explicit register argument
-
-error: positional arguments cannot follow named arguments or explicit register arguments
-  --> $DIR/parse-error.rs:68:36
-   |
-LL |         asm!("{1}", in("eax") foo, const bar);
-   |                     -------------  ^^^^^^^^^ positional argument
-   |                     |
-   |                     explicit register argument
-
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
-  --> $DIR/parse-error.rs:71:29
-   |
-LL |         asm!("", options(), "");
-   |                             ^^ expected one of 9 possible tokens
-
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
-  --> $DIR/parse-error.rs:73:33
-   |
-LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
-   |                                 ^^^^ expected one of 9 possible tokens
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:75:14
-   |
-LL |         asm!(format!("{{{}}}", 0), in(reg) foo);
-   |              ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:77:21
-   |
-LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
-   |                     ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:79:28
-   |
-LL |         asm!("{}", in(reg) _);
-   |                            ^
-
-error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:81:31
-   |
-LL |         asm!("{}", inout(reg) _);
-   |                               ^
-
-error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:83:35
-   |
-LL |         asm!("{}", inlateout(reg) _);
-   |                                   ^
-
-error: requires at least a template string argument
-  --> $DIR/parse-error.rs:90:1
-   |
-LL | global_asm!();
-   | ^^^^^^^^^^^^^^
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:92:13
-   |
-LL | global_asm!(FOO);
-   |             ^^^
-
-error: expected token: `,`
-  --> $DIR/parse-error.rs:94:18
-   |
-LL | global_asm!("{}" FOO);
-   |                  ^^^ expected `,`
-
-error: expected operand, options, or additional template string
-  --> $DIR/parse-error.rs:96:19
-   |
-LL | global_asm!("{}", FOO);
-   |                   ^^^ expected operand, options, or additional template string
-
-error: expected expression, found end of macro arguments
-  --> $DIR/parse-error.rs:98:24
-   |
-LL | global_asm!("{}", const);
-   |                        ^ expected expression
-
-error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
-  --> $DIR/parse-error.rs:100:30
-   |
-LL | global_asm!("{}", const(reg) FOO);
-   |                              ^^^ expected one of `,`, `.`, `?`, or an operator
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
-  --> $DIR/parse-error.rs:102:25
-   |
-LL | global_asm!("", options(FOO));
-   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:104:25
-   |
-LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:106:25
-   |
-LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
-
-error: arguments are not allowed after options
-  --> $DIR/parse-error.rs:108:30
-   |
-LL | global_asm!("{}", options(), const FOO);
-   |                   ---------  ^^^^^^^^^ argument
-   |                   |
-   |                   previous options
-
-error: expected string literal
-  --> $DIR/parse-error.rs:110:29
-   |
-LL | global_asm!("", clobber_abi(FOO));
-   |                             ^^^ not a string literal
-
-error: expected `)`, found `FOO`
-  --> $DIR/parse-error.rs:112:33
-   |
-LL | global_asm!("", clobber_abi("C" FOO));
-   |                                 ^^^ expected `)`
-
-error: expected `)`, found `,`
-  --> $DIR/parse-error.rs:114:32
-   |
-LL | global_asm!("", clobber_abi("C", FOO));
-   |                                ^ expected `)`
-
-error: arguments are not allowed after clobber_abi
-  --> $DIR/parse-error.rs:116:37
-   |
-LL | global_asm!("{}", clobber_abi("C"), const FOO);
-   |                   ----------------  ^^^^^^^^^ argument
-   |                   |
-   |                   clobber_abi
-
-error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:116:19
-   |
-LL | global_asm!("{}", clobber_abi("C"), const FOO);
-   |                   ^^^^^^^^^^^^^^^^
-
-error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:119:28
-   |
-LL | global_asm!("", options(), clobber_abi("C"));
-   |                 ---------  ^^^^^^^^^^^^^^^^
-   |                 |
-   |                 options
-
-error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:121:30
-   |
-LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
-   |                   ---------  ^^^^^^^^^^^^^^^^
-   |                   |
-   |                   options
-
-error: clobber_abi specified multiple times
-  --> $DIR/parse-error.rs:123:35
-   |
-LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
-   |                 ----------------  ^^^^^^^^^^^^^^^^
-   |                 |
-   |                 clobber_abi previously specified here
-
-error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:125:35
-   |
-LL | global_asm!("{a}", a = const FOO, a = const BAR);
-   |                    -------------  ^^^^^^^^^^^^^ duplicate argument
-   |                    |
-   |                    previously here
-
-error: argument never used
-  --> $DIR/parse-error.rs:125:35
-   |
-LL | global_asm!("{a}", a = const FOO, a = const BAR);
-   |                                   ^^^^^^^^^^^^^ argument never used
-   |
-   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
-
-error: expected one of `clobber_abi`, `const`, or `options`, found `""`
-  --> $DIR/parse-error.rs:128:28
-   |
-LL | global_asm!("", options(), "");
-   |                            ^^ expected one of `clobber_abi`, `const`, or `options`
-
-error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
-  --> $DIR/parse-error.rs:130:30
-   |
-LL | global_asm!("{}", const FOO, "{}", const FOO);
-   |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:132:13
-   |
-LL | global_asm!(format!("{{{}}}", 0), const FOO);
-   |             ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: asm template must be a string literal
-  --> $DIR/parse-error.rs:134:20
-   |
-LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
-   |                    ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:37:37
-   |
-LL |     let mut foo = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const foo`
-...
-LL |         asm!("{}", options(), const foo);
-   |                                     ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:46:44
-   |
-LL |     let mut foo = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const foo`
-...
-LL |         asm!("{}", clobber_abi("C"), const foo);
-   |                                            ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:55:31
-   |
-LL |     let mut foo = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const foo`
-...
-LL |         asm!("{a}", a = const foo, a = const bar);
-   |                               ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:55:46
-   |
-LL |     let mut bar = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{a}", a = const foo, a = const bar);
-   |                                              ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:62:46
-   |
-LL |     let mut bar = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                                              ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:65:46
-   |
-LL |     let mut bar = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                                              ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:68:42
-   |
-LL |     let mut bar = 0;
-   |      ---------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{1}", in("eax") foo, const bar);
-   |                                          ^^^ non-constant value
-
-error: aborting due to 66 previous errors
-
-For more information about this error, try `rustc --explain E0435`.
index 9251afd3f059f6c7c661d84a57ee118962c2dd05..1d5d2038aa89caa0c8e4ee056a5e9962cc355d4b 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// only-x86_64
+// needs-asm-support
 
 #![feature(asm, llvm_asm)]
 #![allow(deprecated)] // llvm_asm!
index 1e3bfd077081cf242671ee163c2320cd29d59a63..12be0e666ee141bfad8233f6c3e75f1a7aeec6ff 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// only-x86_64
+// needs-asm-support
 
 #![feature(asm, llvm_asm)]
 #![allow(deprecated)] // llvm_asm!
diff --git a/src/test/ui/asm/srcloc.rs b/src/test/ui/asm/srcloc.rs
deleted file mode 100644 (file)
index ed8cefc..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// min-llvm-version: 10.0.1
-// only-x86_64
-// build-fail
-// compile-flags: -Ccodegen-units=1
-#![feature(asm)]
-
-// Checks that inline asm errors are mapped to the correct line in the source code.
-
-fn main() {
-    unsafe {
-        asm!("invalid_instruction");
-        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!("
-            invalid_instruction
-        ");
-        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(r#"
-            invalid_instruction
-        "#);
-        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!("
-            mov eax, eax
-            invalid_instruction
-            mov eax, eax
-        ");
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(r#"
-            mov eax, eax
-            invalid_instruction
-            mov eax, eax
-        "#);
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(concat!("invalid", "_", "instruction"));
-        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
-        //~^ WARN: scale factor without index register is ignored
-
-        asm!(
-            "invalid_instruction",
-        );
-        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(
-            "mov eax, eax",
-            "invalid_instruction",
-            "mov eax, eax",
-        );
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(
-            "mov eax, eax\n",
-            "invalid_instruction",
-            "mov eax, eax",
-        );
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(
-            "mov eax, eax",
-            concat!("invalid", "_", "instruction"),
-            "mov eax, eax",
-        );
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        asm!(
-            concat!("mov eax", ", ", "eax"),
-            concat!("invalid", "_", "instruction"),
-            concat!("mov eax", ", ", "eax"),
-        );
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
-
-        // Make sure template strings get separated
-        asm!(
-            "invalid_instruction1",
-            "invalid_instruction2",
-        );
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
-        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
-
-        asm!(
-            concat!(
-                "invalid", "_", "instruction1", "\n",
-                "invalid", "_", "instruction2",
-            ),
-        );
-        //~^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
-        //~^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
-
-        asm!(
-            concat!(
-                "invalid", "_", "instruction1", "\n",
-                "invalid", "_", "instruction2",
-            ),
-            concat!(
-                "invalid", "_", "instruction3", "\n",
-                "invalid", "_", "instruction4",
-            ),
-        );
-        //~^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
-        //~^^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
-        //~^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction3'
-        //~^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction4'
-
-        asm!(
-            concat!(
-                "invalid", "_", "instruction1", "\n",
-                "invalid", "_", "instruction2", "\n",
-            ),
-            concat!(
-                "invalid", "_", "instruction3", "\n",
-                "invalid", "_", "instruction4", "\n",
-            ),
-        );
-        //~^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
-        //~^^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
-        //~^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction3'
-        //~^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction4'
-    }
-}
diff --git a/src/test/ui/asm/srcloc.stderr b/src/test/ui/asm/srcloc.stderr
deleted file mode 100644 (file)
index b62c894..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:11:15
-   |
-LL |         asm!("invalid_instruction");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:15:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:20:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:26:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:33:13
-   |
-LL |             invalid_instruction
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:13
-   |
-LL |             invalid_instruction
-   |             ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:38:14
-   |
-LL |         asm!(concat!("invalid", "_", "instruction"));
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-warning: scale factor without index register is ignored
-  --> $DIR/srcloc.rs:41:15
-   |
-LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:23
-   |
-LL |     movaps %xmm3, (%esi, 2)
-   |                          ^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:45:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction
-   |     ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:51:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:58:14
-   |
-LL |             "invalid_instruction",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:65:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction'
-  --> $DIR/srcloc.rs:72:13
-   |
-LL |             concat!("invalid", "_", "instruction"),
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:79:14
-   |
-LL |             "invalid_instruction1",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:80:14
-   |
-LL |             "invalid_instruction2",
-   |              ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:86:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:86:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:95:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:95:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:99:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:4:1
-   |
-LL | invalid_instruction3
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:99:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction4
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction1'
-  --> $DIR/srcloc.rs:110:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:2
-   |
-LL |     invalid_instruction1
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction2'
-  --> $DIR/srcloc.rs:110:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:3:1
-   |
-LL | invalid_instruction2
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction3'
-  --> $DIR/srcloc.rs:114:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:5:1
-   |
-LL | invalid_instruction3
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: invalid instruction mnemonic 'invalid_instruction4'
-  --> $DIR/srcloc.rs:114:13
-   |
-LL |             concat!(
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:6:1
-   |
-LL | invalid_instruction4
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 23 previous errors; 1 warning emitted
-
diff --git a/src/test/ui/asm/sym.rs b/src/test/ui/asm/sym.rs
deleted file mode 100644 (file)
index 634ef01..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// min-llvm-version: 10.0.1
-// only-x86_64
-// only-linux
-// run-pass
-
-#![feature(asm, thread_local)]
-
-extern "C" fn f1() -> i32 {
-    111
-}
-
-// The compiler will generate a shim to hide the caller location parameter.
-#[track_caller]
-fn f2() -> i32 {
-    222
-}
-
-macro_rules! call {
-    ($func:path) => {
-        unsafe {
-            let result: i32;
-            asm!("call {}", sym $func,
-                out("rax") result,
-                out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
-                out("r8") _, out("r9") _, out("r10") _, out("r11") _,
-                out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
-                out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
-                out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
-                out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
-            );
-            result
-        }
-    }
-}
-
-macro_rules! static_addr {
-    ($s:expr) => {
-        unsafe {
-            let result: *const u32;
-            // LEA performs a RIP-relative address calculation and returns the address
-            asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
-            result
-        }
-    }
-}
-macro_rules! static_tls_addr {
-    ($s:expr) => {
-        unsafe {
-            let result: *const u32;
-            asm!(
-                "
-                    # Load TLS base address
-                    mov {out}, qword ptr fs:[0]
-                    # Calculate the address of sym in the TLS block. The @tpoff
-                    # relocation gives the offset of the symbol from the start
-                    # of the TLS block.
-                    lea {out}, [{out} + {sym}@tpoff]
-                ",
-                out = out(reg) result,
-                sym = sym $s
-            );
-            result
-        }
-    }
-}
-
-static S1: u32 = 111;
-#[thread_local]
-static S2: u32 = 222;
-
-fn main() {
-    assert_eq!(call!(f1), 111);
-    assert_eq!(call!(f2), 222);
-    assert_eq!(static_addr!(S1), &S1 as *const u32);
-    assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
-    std::thread::spawn(|| {
-        assert_eq!(static_addr!(S1), &S1 as *const u32);
-        assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
-    }).join().unwrap();
-}
index 5e38fb70a4adfd7240d7506e9ab238d13d52f7ff..bbbe798d1557b0e095559ae2cff6fcfd19ebede2 100644 (file)
@@ -1,4 +1,7 @@
-// only-x86_64
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
 
 #![feature(asm, global_asm)]
 
@@ -49,6 +52,8 @@ const fn const_bar<T>(x: T) -> T {
         //~^ ERROR mismatched types
         asm!("{}", const 0 as *mut u8);
         //~^ ERROR mismatched types
+        asm!("{}", const &0);
+        //~^ ERROR mismatched types
     }
 }
 
index 5edbcf4a2a7c939a327dc66b1a9e8042d31de97a..c9080a3c0309a2fa819c2e981b95933a572ffce8 100644 (file)
@@ -1,5 +1,5 @@
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/type-check-1.rs:34:26
+  --> $DIR/type-check-1.rs:37:26
    |
 LL |         let x = 0;
    |         ----- help: consider using `const` instead of `let`: `const x`
@@ -8,7 +8,7 @@ LL |         asm!("{}", const x);
    |                          ^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/type-check-1.rs:37:36
+  --> $DIR/type-check-1.rs:40:36
    |
 LL |         let x = 0;
    |         ----- help: consider using `const` instead of `let`: `const x`
@@ -17,7 +17,7 @@ LL |         asm!("{}", const const_foo(x));
    |                                    ^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/type-check-1.rs:40:36
+  --> $DIR/type-check-1.rs:43:36
    |
 LL |         let x = 0;
    |         ----- help: consider using `const` instead of `let`: `const x`
@@ -26,13 +26,13 @@ LL |         asm!("{}", const const_bar(x));
    |                                    ^ non-constant value
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:48:26
+  --> $DIR/type-check-1.rs:51:26
    |
 LL |         asm!("{}", const 0f32);
    |                          ^^^^ expected integer, found `f32`
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:50:26
+  --> $DIR/type-check-1.rs:53:26
    |
 LL |         asm!("{}", const 0 as *mut u8);
    |                          ^^^^^^^^^^^^ expected integer, found *-ptr
@@ -40,20 +40,32 @@ LL |         asm!("{}", const 0 as *mut u8);
    = note:     expected type `{integer}`
            found raw pointer `*mut u8`
 
+error[E0308]: mismatched types
+  --> $DIR/type-check-1.rs:55:26
+   |
+LL |         asm!("{}", const &0);
+   |                          ^^ expected integer, found `&{integer}`
+   |
+help: consider removing the borrow
+   |
+LL -         asm!("{}", const &0);
+LL +         asm!("{}", const 0);
+   | 
+
 error: invalid asm output
-  --> $DIR/type-check-1.rs:10:29
+  --> $DIR/type-check-1.rs:13:29
    |
 LL |         asm!("{}", out(reg) 1 + 2);
    |                             ^^^^^ cannot assign to this expression
 
 error: invalid asm output
-  --> $DIR/type-check-1.rs:12:31
+  --> $DIR/type-check-1.rs:15:31
    |
 LL |         asm!("{}", inout(reg) 1 + 2);
    |                               ^^^^^ cannot assign to this expression
 
 error[E0277]: the size for values of type `[u64]` cannot be known at compilation time
-  --> $DIR/type-check-1.rs:18:28
+  --> $DIR/type-check-1.rs:21:28
    |
 LL |         asm!("{}", in(reg) v[..]);
    |                            ^^^^^ doesn't have a size known at compile-time
@@ -62,7 +74,7 @@ LL |         asm!("{}", in(reg) v[..]);
    = note: all inline asm arguments must have a statically known size
 
 error[E0277]: the size for values of type `[u64]` cannot be known at compilation time
-  --> $DIR/type-check-1.rs:20:29
+  --> $DIR/type-check-1.rs:23:29
    |
 LL |         asm!("{}", out(reg) v[..]);
    |                             ^^^^^ doesn't have a size known at compile-time
@@ -71,7 +83,7 @@ LL |         asm!("{}", out(reg) v[..]);
    = note: all inline asm arguments must have a statically known size
 
 error[E0277]: the size for values of type `[u64]` cannot be known at compilation time
-  --> $DIR/type-check-1.rs:22:31
+  --> $DIR/type-check-1.rs:25:31
    |
 LL |         asm!("{}", inout(reg) v[..]);
    |                               ^^^^^ doesn't have a size known at compile-time
@@ -80,13 +92,13 @@ LL |         asm!("{}", inout(reg) v[..]);
    = note: all inline asm arguments must have a statically known size
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:60:25
+  --> $DIR/type-check-1.rs:65:25
    |
 LL | global_asm!("{}", const 0f32);
    |                         ^^^^ expected integer, found `f32`
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:62:25
+  --> $DIR/type-check-1.rs:67:25
    |
 LL | global_asm!("{}", const 0 as *mut u8);
    |                         ^^^^^^^^^^^^ expected integer, found *-ptr
@@ -94,7 +106,7 @@ LL | global_asm!("{}", const 0 as *mut u8);
    = note:     expected type `{integer}`
            found raw pointer `*mut u8`
 
-error: aborting due to 12 previous errors
+error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0435.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/asm/type-check-2.rs b/src/test/ui/asm/type-check-2.rs
deleted file mode 100644 (file)
index c70a880..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// only-x86_64
-
-#![feature(asm, repr_simd, never_type)]
-
-#[repr(simd)]
-struct SimdNonCopy(f32, f32, f32, f32);
-
-fn main() {
-    unsafe {
-        // Inputs must be initialized
-
-        let x: u64;
-        asm!("{}", in(reg) x);
-        //~^ ERROR use of possibly-uninitialized variable: `x`
-        let mut y: u64;
-        asm!("{}", inout(reg) y);
-        //~^ ERROR use of possibly-uninitialized variable: `y`
-        let _ = y;
-
-        // Outputs require mutable places
-
-        let v: Vec<u64> = vec![0, 1, 2];
-        asm!("{}", in(reg) v[0]);
-        asm!("{}", out(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
-        asm!("{}", inout(reg) v[0]);
-        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
-
-        // This currently causes an ICE: https://github.com/rust-lang/rust/issues/81857
-        // asm!("{}", const &0);
-        // ERROR asm `const` arguments must be integer or floating-point values
-
-        // Sym operands must point to a function or static
-
-        const C: i32 = 0;
-        static S: i32 = 0;
-        asm!("{}", sym S);
-        asm!("{}", sym main);
-        asm!("{}", sym C);
-        //~^ ERROR asm `sym` operand must point to a fn or static
-        asm!("{}", sym x);
-        //~^ ERROR asm `sym` operand must point to a fn or static
-
-        // Register operands must be Copy
-
-        asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
-        //~^ ERROR arguments for inline assembly must be copyable
-
-        // Register operands must be integers, floats, SIMD vectors, pointers or
-        // function pointers.
-
-        asm!("{}", in(reg) 0i64);
-        asm!("{}", in(reg) 0f64);
-        asm!("{}", in(xmm_reg) std::arch::x86_64::_mm_setzero_ps());
-        asm!("{}", in(reg) 0 as *const u8);
-        asm!("{}", in(reg) 0 as *mut u8);
-        asm!("{}", in(reg) main as fn());
-        asm!("{}", in(reg) |x: i32| x);
-        //~^ ERROR cannot use value of type
-        asm!("{}", in(reg) vec![0]);
-        //~^ ERROR cannot use value of type `Vec<i32>` for inline assembly
-        asm!("{}", in(reg) (1, 2, 3));
-        //~^ ERROR cannot use value of type `(i32, i32, i32)` for inline assembly
-        asm!("{}", in(reg) [1, 2, 3]);
-        //~^ ERROR cannot use value of type `[i32; 3]` for inline assembly
-
-        // Register inputs (but not outputs) allow references and function types
-
-        let mut f = main;
-        let mut r = &mut 0;
-        asm!("{}", in(reg) f);
-        asm!("{}", inout(reg) f);
-        //~^ ERROR cannot use value of type `fn() {main}` for inline assembly
-        asm!("{}", in(reg) r);
-        asm!("{}", inout(reg) r);
-        //~^ ERROR cannot use value of type `&mut i32` for inline assembly
-        let _ = (f, r);
-
-        // Type checks ignore never type
-
-        let u: ! = unreachable!();
-        asm!("{}", in(reg) u);
-    }
-}
diff --git a/src/test/ui/asm/type-check-2.stderr b/src/test/ui/asm/type-check-2.stderr
deleted file mode 100644 (file)
index 1354a9d..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-error: arguments for inline assembly must be copyable
-  --> $DIR/type-check-2.rs:46:32
-   |
-LL |         asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `SimdNonCopy` does not implement the Copy trait
-
-error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly
-  --> $DIR/type-check-2.rs:58:28
-   |
-LL |         asm!("{}", in(reg) |x: i32| x);
-   |                            ^^^^^^^^^^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-
-error: cannot use value of type `Vec<i32>` for inline assembly
-  --> $DIR/type-check-2.rs:60:28
-   |
-LL |         asm!("{}", in(reg) vec![0]);
-   |                            ^^^^^^^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: cannot use value of type `(i32, i32, i32)` for inline assembly
-  --> $DIR/type-check-2.rs:62:28
-   |
-LL |         asm!("{}", in(reg) (1, 2, 3));
-   |                            ^^^^^^^^^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-
-error: cannot use value of type `[i32; 3]` for inline assembly
-  --> $DIR/type-check-2.rs:64:28
-   |
-LL |         asm!("{}", in(reg) [1, 2, 3]);
-   |                            ^^^^^^^^^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-
-error: cannot use value of type `fn() {main}` for inline assembly
-  --> $DIR/type-check-2.rs:72:31
-   |
-LL |         asm!("{}", inout(reg) f);
-   |                               ^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-
-error: cannot use value of type `&mut i32` for inline assembly
-  --> $DIR/type-check-2.rs:75:31
-   |
-LL |         asm!("{}", inout(reg) r);
-   |                               ^
-   |
-   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
-
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:39:24
-   |
-LL |         asm!("{}", sym C);
-   |                        ^
-
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:41:24
-   |
-LL |         asm!("{}", sym x);
-   |                        ^
-
-error[E0381]: use of possibly-uninitialized variable: `x`
-  --> $DIR/type-check-2.rs:13:28
-   |
-LL |         asm!("{}", in(reg) x);
-   |                            ^ use of possibly-uninitialized `x`
-
-error[E0381]: use of possibly-uninitialized variable: `y`
-  --> $DIR/type-check-2.rs:16:9
-   |
-LL |         asm!("{}", inout(reg) y);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
-
-error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-2.rs:24:29
-   |
-LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
-LL |         asm!("{}", in(reg) v[0]);
-LL |         asm!("{}", out(reg) v[0]);
-   |                             ^ cannot borrow as mutable
-
-error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-2.rs:26:31
-   |
-LL |         let v: Vec<u64> = vec![0, 1, 2];
-   |             - help: consider changing this to be mutable: `mut v`
-...
-LL |         asm!("{}", inout(reg) v[0]);
-   |                               ^ cannot borrow as mutable
-
-error: aborting due to 13 previous errors
-
-Some errors have detailed explanations: E0381, E0596.
-For more information about an error, try `rustc --explain E0381`.
diff --git a/src/test/ui/asm/type-check-3.rs b/src/test/ui/asm/type-check-3.rs
deleted file mode 100644 (file)
index c2c1885..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// only-x86_64
-// compile-flags: -C target-feature=+avx512f
-
-#![feature(asm, global_asm)]
-
-use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps};
-
-fn main() {
-    unsafe {
-        // Types must be listed in the register class.
-
-        asm!("{}", in(reg) 0i128);
-        //~^ ERROR type `i128` cannot be used with this register class
-        asm!("{}", in(reg) _mm_setzero_ps());
-        //~^ ERROR type `__m128` cannot be used with this register class
-        asm!("{}", in(reg) _mm256_setzero_ps());
-        //~^ ERROR type `__m256` cannot be used with this register class
-        asm!("{}", in(xmm_reg) 0u8);
-        //~^ ERROR type `u8` cannot be used with this register class
-        asm!("{:e}", in(reg) 0i32);
-        asm!("{}", in(xmm_reg) 0i32);
-        asm!("{:e}", in(reg) 0f32);
-        asm!("{}", in(xmm_reg) 0f32);
-        asm!("{}", in(xmm_reg) _mm_setzero_ps());
-        asm!("{:x}", in(ymm_reg) _mm_setzero_ps());
-        asm!("{}", in(kreg) 0u16);
-        asm!("{}", in(kreg) 0u64);
-        //~^ ERROR `avx512bw` target feature is not enabled
-
-        // Template modifier suggestions for sub-registers
-
-        asm!("{0} {0}", in(reg) 0i16);
-        //~^ WARN formatting may not be suitable for sub-register argument
-        asm!("{0} {0:x}", in(reg) 0i16);
-        //~^ WARN formatting may not be suitable for sub-register argument
-        asm!("{}", in(reg) 0i32);
-        //~^ WARN formatting may not be suitable for sub-register argument
-        asm!("{}", in(reg) 0i64);
-        asm!("{}", in(ymm_reg) 0i64);
-        //~^ WARN formatting may not be suitable for sub-register argument
-        asm!("{}", in(ymm_reg) _mm256_setzero_ps());
-        asm!("{:l}", in(reg) 0i16);
-        asm!("{:l}", in(reg) 0i32);
-        asm!("{:l}", in(reg) 0i64);
-        asm!("{:x}", in(ymm_reg) 0i64);
-        asm!("{:x}", in(ymm_reg) _mm256_setzero_ps());
-
-        // Suggest different register class for type
-
-        asm!("{}", in(reg) 0i8);
-        //~^ ERROR type `i8` cannot be used with this register class
-        asm!("{}", in(reg_byte) 0i8);
-
-        // Split inout operands must have compatible types
-
-        let mut val_i16: i16;
-        let mut val_f32: f32;
-        let mut val_u32: u32;
-        let mut val_u64: u64;
-        let mut val_ptr: *mut u8;
-        asm!("{:r}", inout(reg) 0u16 => val_i16);
-        asm!("{:r}", inout(reg) 0u32 => val_f32);
-        //~^ ERROR incompatible types for asm inout argument
-        asm!("{:r}", inout(reg) 0u32 => val_ptr);
-        //~^ ERROR incompatible types for asm inout argument
-        asm!("{:r}", inout(reg) main => val_u32);
-        //~^ ERROR incompatible types for asm inout argument
-        asm!("{:r}", inout(reg) 0u64 => val_ptr);
-        asm!("{:r}", inout(reg) main => val_u64);
-    }
-}
-
-// Constants must be... constant
-
-static S: i32 = 1;
-const fn const_foo(x: i32) -> i32 {
-    x
-}
-const fn const_bar<T>(x: T) -> T {
-    x
-}
-global_asm!("{}", const S);
-//~^ ERROR constants cannot refer to statics
-global_asm!("{}", const const_foo(0));
-global_asm!("{}", const const_foo(S));
-//~^ ERROR constants cannot refer to statics
-global_asm!("{}", const const_bar(0));
-global_asm!("{}", const const_bar(S));
-//~^ ERROR constants cannot refer to statics
diff --git a/src/test/ui/asm/type-check-3.stderr b/src/test/ui/asm/type-check-3.stderr
deleted file mode 100644 (file)
index 9f6989c..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-error: type `i128` cannot be used with this register class
-  --> $DIR/type-check-3.rs:12:28
-   |
-LL |         asm!("{}", in(reg) 0i128);
-   |                            ^^^^^
-   |
-   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
-
-error: type `__m128` cannot be used with this register class
-  --> $DIR/type-check-3.rs:14:28
-   |
-LL |         asm!("{}", in(reg) _mm_setzero_ps());
-   |                            ^^^^^^^^^^^^^^^^
-   |
-   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
-
-error: type `__m256` cannot be used with this register class
-  --> $DIR/type-check-3.rs:16:28
-   |
-LL |         asm!("{}", in(reg) _mm256_setzero_ps());
-   |                            ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
-
-error: type `u8` cannot be used with this register class
-  --> $DIR/type-check-3.rs:18:32
-   |
-LL |         asm!("{}", in(xmm_reg) 0u8);
-   |                                ^^^
-   |
-   = note: register class `xmm_reg` supports these types: i32, i64, f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
-
-error: `avx512bw` target feature is not enabled
-  --> $DIR/type-check-3.rs:27:29
-   |
-LL |         asm!("{}", in(kreg) 0u64);
-   |                             ^^^^
-   |
-   = note: this is required to use type `u64` with register class `kreg`
-
-warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:32:15
-   |
-LL |         asm!("{0} {0}", in(reg) 0i16);
-   |               ^^^ ^^^           ---- for this argument
-   |
-   = note: `#[warn(asm_sub_register)]` on by default
-   = help: use the `x` modifier to have the register formatted as `ax`
-   = help: or use the `r` modifier to keep the default formatting of `rax`
-
-warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:34:15
-   |
-LL |         asm!("{0} {0:x}", in(reg) 0i16);
-   |               ^^^                 ---- for this argument
-   |
-   = help: use the `x` modifier to have the register formatted as `ax`
-   = help: or use the `r` modifier to keep the default formatting of `rax`
-
-warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:36:15
-   |
-LL |         asm!("{}", in(reg) 0i32);
-   |               ^^           ---- for this argument
-   |
-   = help: use the `e` modifier to have the register formatted as `eax`
-   = help: or use the `r` modifier to keep the default formatting of `rax`
-
-warning: formatting may not be suitable for sub-register argument
-  --> $DIR/type-check-3.rs:39:15
-   |
-LL |         asm!("{}", in(ymm_reg) 0i64);
-   |               ^^               ---- for this argument
-   |
-   = help: use the `x` modifier to have the register formatted as `xmm0`
-   = help: or use the `y` modifier to keep the default formatting of `ymm0`
-
-error: type `i8` cannot be used with this register class
-  --> $DIR/type-check-3.rs:50:28
-   |
-LL |         asm!("{}", in(reg) 0i8);
-   |                            ^^^
-   |
-   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
-   = help: consider using the `reg_byte` register class instead
-
-error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:62:33
-   |
-LL |         asm!("{:r}", inout(reg) 0u32 => val_f32);
-   |                                 ^^^^    ^^^^^^^ type `f32`
-   |                                 |
-   |                                 type `u32`
-   |
-   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
-
-error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:64:33
-   |
-LL |         asm!("{:r}", inout(reg) 0u32 => val_ptr);
-   |                                 ^^^^    ^^^^^^^ type `*mut u8`
-   |                                 |
-   |                                 type `u32`
-   |
-   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
-
-error: incompatible types for asm inout argument
-  --> $DIR/type-check-3.rs:66:33
-   |
-LL |         asm!("{:r}", inout(reg) main => val_u32);
-   |                                 ^^^^    ^^^^^^^ type `u32`
-   |                                 |
-   |                                 type `fn()`
-   |
-   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
-
-error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:82:25
-   |
-LL | global_asm!("{}", const S);
-   |                         ^
-   |
-   = help: consider extracting the value of the `static` to a `const`, and referring to that
-
-error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:85:35
-   |
-LL | global_asm!("{}", const const_foo(S));
-   |                                   ^
-   |
-   = help: consider extracting the value of the `static` to a `const`, and referring to that
-
-error[E0013]: constants cannot refer to statics
-  --> $DIR/type-check-3.rs:88:35
-   |
-LL | global_asm!("{}", const const_bar(S));
-   |                                   ^
-   |
-   = help: consider extracting the value of the `static` to a `const`, and referring to that
-
-error: aborting due to 12 previous errors; 4 warnings emitted
-
-For more information about this error, try `rustc --explain E0013`.
index 2be627c11657b4b95e645d3a5af41bc78bd3d5ce..c9826662009857fb5d0e02c1f3c31e199a4e7842 100644 (file)
@@ -1,4 +1,7 @@
-// only-x86_64
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
 
 #![feature(asm)]
 
index 8035bbefc1aa1156ffc700fb77b9eff2fcc8c727..db2bf0a69f7fcd50c5e1e3f8c19e87db6f9c3c0a 100644 (file)
@@ -1,5 +1,5 @@
 error[E0506]: cannot assign to `a` because it is borrowed
-  --> $DIR/type-check-4.rs:11:9
+  --> $DIR/type-check-4.rs:14:9
    |
 LL |         let p = &a;
    |                 -- borrow of `a` occurs here
@@ -10,7 +10,7 @@ LL |         println!("{}", p);
    |                        - borrow later used here
 
 error[E0503]: cannot use `a` because it was mutably borrowed
-  --> $DIR/type-check-4.rs:19:28
+  --> $DIR/type-check-4.rs:22:28
    |
 LL |         let p = &mut a;
    |                 ------ borrow of `a` occurs here
diff --git a/src/test/ui/asm/x86_64/bad-options.rs b/src/test/ui/asm/x86_64/bad-options.rs
new file mode 100644 (file)
index 0000000..dc61d16
--- /dev/null
@@ -0,0 +1,39 @@
+// only-x86_64
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    let mut foo = 0;
+    unsafe {
+        asm!("", options(nomem, readonly));
+        //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
+        asm!("", options(pure, nomem, noreturn));
+        //~^ ERROR the `pure` and `noreturn` options are mutually exclusive
+        //~^^ ERROR asm with the `pure` option must have at least one output
+        asm!("{}", in(reg) foo, options(pure, nomem));
+        //~^ ERROR asm with the `pure` option must have at least one output
+        asm!("{}", out(reg) foo, options(noreturn));
+        //~^ ERROR asm outputs are not allowed with the `noreturn` option
+    }
+
+    unsafe {
+        asm!("", clobber_abi("foo"));
+        //~^ ERROR invalid ABI for `clobber_abi`
+        asm!("{}", out(reg) foo, clobber_abi("C"));
+        //~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs
+        asm!("", out("eax") foo, clobber_abi("C"));
+    }
+}
+
+global_asm!("", options(nomem));
+//~^ ERROR expected one of
+global_asm!("", options(readonly));
+//~^ ERROR expected one of
+global_asm!("", options(noreturn));
+//~^ ERROR expected one of
+global_asm!("", options(pure));
+//~^ ERROR expected one of
+global_asm!("", options(nostack));
+//~^ ERROR expected one of
+global_asm!("", options(preserves_flags));
+//~^ ERROR expected one of
diff --git a/src/test/ui/asm/x86_64/bad-options.stderr b/src/test/ui/asm/x86_64/bad-options.stderr
new file mode 100644 (file)
index 0000000..8cfd450
--- /dev/null
@@ -0,0 +1,84 @@
+error: the `nomem` and `readonly` options are mutually exclusive
+  --> $DIR/bad-options.rs:8:18
+   |
+LL |         asm!("", options(nomem, readonly));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `pure` and `noreturn` options are mutually exclusive
+  --> $DIR/bad-options.rs:10:18
+   |
+LL |         asm!("", options(pure, nomem, noreturn));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: asm with the `pure` option must have at least one output
+  --> $DIR/bad-options.rs:10:18
+   |
+LL |         asm!("", options(pure, nomem, noreturn));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: asm with the `pure` option must have at least one output
+  --> $DIR/bad-options.rs:13:33
+   |
+LL |         asm!("{}", in(reg) foo, options(pure, nomem));
+   |                                 ^^^^^^^^^^^^^^^^^^^^
+
+error: asm outputs are not allowed with the `noreturn` option
+  --> $DIR/bad-options.rs:15:20
+   |
+LL |         asm!("{}", out(reg) foo, options(noreturn));
+   |                    ^^^^^^^^^^^^
+
+error: asm with `clobber_abi` must specify explicit registers for outputs
+  --> $DIR/bad-options.rs:22:20
+   |
+LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
+   |                    ^^^^^^^^^^^^  ---------------- clobber_abi
+   |                    |
+   |                    generic outputs
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/bad-options.rs:28:25
+   |
+LL | global_asm!("", options(nomem));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
+  --> $DIR/bad-options.rs:30:25
+   |
+LL | global_asm!("", options(readonly));
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
+  --> $DIR/bad-options.rs:32:25
+   |
+LL | global_asm!("", options(noreturn));
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
+  --> $DIR/bad-options.rs:34:25
+   |
+LL | global_asm!("", options(pure));
+   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
+  --> $DIR/bad-options.rs:36:25
+   |
+LL | global_asm!("", options(nostack));
+   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
+  --> $DIR/bad-options.rs:38:25
+   |
+LL | global_asm!("", options(preserves_flags));
+   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: invalid ABI for `clobber_abi`
+  --> $DIR/bad-options.rs:20:18
+   |
+LL |         asm!("", clobber_abi("foo"));
+   |                  ^^^^^^^^^^^^^^^^^^
+   |
+   = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs
new file mode 100644 (file)
index 0000000..06af08f
--- /dev/null
@@ -0,0 +1,68 @@
+// only-x86_64
+// compile-flags: -C target-feature=+avx2
+
+#![feature(asm)]
+
+fn main() {
+    let mut foo = 0;
+    let mut bar = 0;
+    unsafe {
+        // Bad register/register class
+
+        asm!("{}", in(foo) foo);
+        //~^ ERROR invalid register class `foo`: unknown register class
+        asm!("", in("foo") foo);
+        //~^ ERROR invalid register `foo`: unknown register
+        asm!("{:z}", in(reg) foo);
+        //~^ ERROR invalid asm template modifier for this register class
+        asm!("{:r}", in(xmm_reg) foo);
+        //~^ ERROR invalid asm template modifier for this register class
+        asm!("{:a}", const 0);
+        //~^ ERROR asm template modifiers are not allowed for `const` arguments
+        asm!("{:a}", sym main);
+        //~^ ERROR asm template modifiers are not allowed for `sym` arguments
+        asm!("{}", in(zmm_reg) foo);
+        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
+        asm!("", in("zmm0") foo);
+        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
+        asm!("", in("ebp") foo);
+        //~^ ERROR invalid register `ebp`: the frame pointer cannot be used as an operand
+        asm!("", in("rsp") foo);
+        //~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
+        asm!("", in("ip") foo);
+        //~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
+        asm!("", in("k0") foo);
+        //~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
+        asm!("", in("ah") foo);
+        //~^ ERROR invalid register `ah`: high byte registers cannot be used as an operand
+
+        asm!("", in("st(2)") foo);
+        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
+        asm!("", in("mm0") foo);
+        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
+        asm!("", out("st(2)") _);
+        asm!("", out("mm0") _);
+        asm!("{}", in(x87_reg) foo);
+        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
+        asm!("{}", in(mmx_reg) foo);
+        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
+        asm!("{}", out(x87_reg) _);
+        //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
+        asm!("{}", out(mmx_reg) _);
+        //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
+
+        // Explicit register conflicts
+        // (except in/lateout which don't conflict)
+
+        asm!("", in("eax") foo, in("al") bar);
+        //~^ ERROR register `al` conflicts with register `ax`
+        asm!("", in("rax") foo, out("rax") bar);
+        //~^ ERROR register `ax` conflicts with register `ax`
+        asm!("", in("al") foo, lateout("al") bar);
+        asm!("", in("xmm0") foo, in("ymm0") bar);
+        //~^ ERROR register `ymm0` conflicts with register `xmm0`
+        asm!("", in("xmm0") foo, out("ymm0") bar);
+        //~^ ERROR register `ymm0` conflicts with register `xmm0`
+        asm!("", in("xmm0") foo, lateout("ymm0") bar);
+    }
+}
diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr
new file mode 100644 (file)
index 0000000..14740bf
--- /dev/null
@@ -0,0 +1,172 @@
+error: invalid register class `foo`: unknown register class
+  --> $DIR/bad-reg.rs:12:20
+   |
+LL |         asm!("{}", in(foo) foo);
+   |                    ^^^^^^^^^^^
+
+error: invalid register `foo`: unknown register
+  --> $DIR/bad-reg.rs:14:18
+   |
+LL |         asm!("", in("foo") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid asm template modifier for this register class
+  --> $DIR/bad-reg.rs:16:15
+   |
+LL |         asm!("{:z}", in(reg) foo);
+   |               ^^^^   ----------- argument
+   |               |
+   |               template modifier
+   |
+   = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, `r`
+
+error: invalid asm template modifier for this register class
+  --> $DIR/bad-reg.rs:18:15
+   |
+LL |         asm!("{:r}", in(xmm_reg) foo);
+   |               ^^^^   --------------- argument
+   |               |
+   |               template modifier
+   |
+   = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, `z`
+
+error: asm template modifiers are not allowed for `const` arguments
+  --> $DIR/bad-reg.rs:20:15
+   |
+LL |         asm!("{:a}", const 0);
+   |               ^^^^   ------- argument
+   |               |
+   |               template modifier
+
+error: asm template modifiers are not allowed for `sym` arguments
+  --> $DIR/bad-reg.rs:22:15
+   |
+LL |         asm!("{:a}", sym main);
+   |               ^^^^   -------- argument
+   |               |
+   |               template modifier
+
+error: register class `zmm_reg` requires the `avx512f` target feature
+  --> $DIR/bad-reg.rs:24:20
+   |
+LL |         asm!("{}", in(zmm_reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: register class `zmm_reg` requires the `avx512f` target feature
+  --> $DIR/bad-reg.rs:26:18
+   |
+LL |         asm!("", in("zmm0") foo);
+   |                  ^^^^^^^^^^^^^^
+
+error: invalid register `ebp`: the frame pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:28:18
+   |
+LL |         asm!("", in("ebp") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid register `rsp`: the stack pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:30:18
+   |
+LL |         asm!("", in("rsp") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: invalid register `ip`: the instruction pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:32:18
+   |
+LL |         asm!("", in("ip") foo);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:34:18
+   |
+LL |         asm!("", in("k0") foo);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64
+  --> $DIR/bad-reg.rs:36:18
+   |
+LL |         asm!("", in("ah") foo);
+   |                  ^^^^^^^^^^^^
+
+error: register class `x87_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:39:18
+   |
+LL |         asm!("", in("st(2)") foo);
+   |                  ^^^^^^^^^^^^^^^
+
+error: register class `mmx_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:41:18
+   |
+LL |         asm!("", in("mm0") foo);
+   |                  ^^^^^^^^^^^^^
+
+error: register class `x87_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:45:20
+   |
+LL |         asm!("{}", in(x87_reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: register class `mmx_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:47:20
+   |
+LL |         asm!("{}", in(mmx_reg) foo);
+   |                    ^^^^^^^^^^^^^^^
+
+error: register class `x87_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:49:20
+   |
+LL |         asm!("{}", out(x87_reg) _);
+   |                    ^^^^^^^^^^^^^^
+
+error: register class `mmx_reg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:51:20
+   |
+LL |         asm!("{}", out(mmx_reg) _);
+   |                    ^^^^^^^^^^^^^^
+
+error: register `al` conflicts with register `ax`
+  --> $DIR/bad-reg.rs:57:33
+   |
+LL |         asm!("", in("eax") foo, in("al") bar);
+   |                  -------------  ^^^^^^^^^^^^ register `al`
+   |                  |
+   |                  register `ax`
+
+error: register `ax` conflicts with register `ax`
+  --> $DIR/bad-reg.rs:59:33
+   |
+LL |         asm!("", in("rax") foo, out("rax") bar);
+   |                  -------------  ^^^^^^^^^^^^^^ register `ax`
+   |                  |
+   |                  register `ax`
+   |
+help: use `lateout` instead of `out` to avoid conflict
+  --> $DIR/bad-reg.rs:59:18
+   |
+LL |         asm!("", in("rax") foo, out("rax") bar);
+   |                  ^^^^^^^^^^^^^
+
+error: register `ymm0` conflicts with register `xmm0`
+  --> $DIR/bad-reg.rs:62:34
+   |
+LL |         asm!("", in("xmm0") foo, in("ymm0") bar);
+   |                  --------------  ^^^^^^^^^^^^^^ register `ymm0`
+   |                  |
+   |                  register `xmm0`
+
+error: register `ymm0` conflicts with register `xmm0`
+  --> $DIR/bad-reg.rs:64:34
+   |
+LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
+   |                  --------------  ^^^^^^^^^^^^^^^ register `ymm0`
+   |                  |
+   |                  register `xmm0`
+   |
+help: use `lateout` instead of `out` to avoid conflict
+  --> $DIR/bad-reg.rs:64:18
+   |
+LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
+   |                  ^^^^^^^^^^^^^^
+
+error: aborting due to 23 previous errors
+
diff --git a/src/test/ui/asm/x86_64/const.rs b/src/test/ui/asm/x86_64/const.rs
new file mode 100644 (file)
index 0000000..d4de9ab
--- /dev/null
@@ -0,0 +1,42 @@
+// min-llvm-version: 10.0.1
+// only-x86_64
+// run-pass
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(asm, global_asm)]
+
+fn const_generic<const X: usize>() -> usize {
+    unsafe {
+        let a: usize;
+        asm!("mov {}, {}", out(reg) a, const X);
+        a
+    }
+}
+
+const fn constfn(x: usize) -> usize {
+    x
+}
+
+fn main() {
+    unsafe {
+        let a: usize;
+        asm!("mov {}, {}", out(reg) a, const 5);
+        assert_eq!(a, 5);
+
+        let b: usize;
+        asm!("mov {}, {}", out(reg) b, const constfn(5));
+        assert_eq!(b, 5);
+
+        let c: usize;
+        asm!("mov {}, {}", out(reg) c, const constfn(5) + constfn(5));
+        assert_eq!(c, 10);
+    }
+
+    let d = const_generic::<5>();
+    assert_eq!(d, 5);
+}
+
+global_asm!("mov eax, {}", const 5);
+global_asm!("mov eax, {}", const constfn(5));
+global_asm!("mov eax, {}", const constfn(5) + constfn(5));
diff --git a/src/test/ui/asm/x86_64/duplicate-options.fixed b/src/test/ui/asm/x86_64/duplicate-options.fixed
new file mode 100644 (file)
index 0000000..d4444e9
--- /dev/null
@@ -0,0 +1,29 @@
+// only-x86_64
+// run-rustfix
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    unsafe {
+        asm!("", options(nomem, ));
+        //~^ ERROR the `nomem` option was already provided
+        asm!("", options(att_syntax, ));
+        //~^ ERROR the `att_syntax` option was already provided
+        asm!("", options(nostack, att_syntax), options());
+        //~^ ERROR the `nostack` option was already provided
+        asm!("", options(nostack, ), options(), options());
+        //~^ ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        asm!(
+            "",
+            options(nomem, noreturn),
+            options(att_syntax, ), //~ ERROR the `noreturn` option was already provided
+            options( nostack), //~ ERROR the `nomem` option was already provided
+            options(), //~ ERROR the `noreturn` option was already provided
+        );
+    }
+}
+
+global_asm!("", options(att_syntax, ));
+//~^ ERROR the `att_syntax` option was already provided
diff --git a/src/test/ui/asm/x86_64/duplicate-options.rs b/src/test/ui/asm/x86_64/duplicate-options.rs
new file mode 100644 (file)
index 0000000..fd28311
--- /dev/null
@@ -0,0 +1,29 @@
+// only-x86_64
+// run-rustfix
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    unsafe {
+        asm!("", options(nomem, nomem));
+        //~^ ERROR the `nomem` option was already provided
+        asm!("", options(att_syntax, att_syntax));
+        //~^ ERROR the `att_syntax` option was already provided
+        asm!("", options(nostack, att_syntax), options(nostack));
+        //~^ ERROR the `nostack` option was already provided
+        asm!("", options(nostack, nostack), options(nostack), options(nostack));
+        //~^ ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        //~| ERROR the `nostack` option was already provided
+        asm!(
+            "",
+            options(nomem, noreturn),
+            options(att_syntax, noreturn), //~ ERROR the `noreturn` option was already provided
+            options(nomem, nostack), //~ ERROR the `nomem` option was already provided
+            options(noreturn), //~ ERROR the `noreturn` option was already provided
+        );
+    }
+}
+
+global_asm!("", options(att_syntax, att_syntax));
+//~^ ERROR the `att_syntax` option was already provided
diff --git a/src/test/ui/asm/x86_64/duplicate-options.stderr b/src/test/ui/asm/x86_64/duplicate-options.stderr
new file mode 100644 (file)
index 0000000..53edf8f
--- /dev/null
@@ -0,0 +1,62 @@
+error: the `nomem` option was already provided
+  --> $DIR/duplicate-options.rs:8:33
+   |
+LL |         asm!("", options(nomem, nomem));
+   |                                 ^^^^^ this option was already provided
+
+error: the `att_syntax` option was already provided
+  --> $DIR/duplicate-options.rs:10:38
+   |
+LL |         asm!("", options(att_syntax, att_syntax));
+   |                                      ^^^^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:12:56
+   |
+LL |         asm!("", options(nostack, att_syntax), options(nostack));
+   |                                                        ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:35
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                   ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:53
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                                     ^^^^^^^ this option was already provided
+
+error: the `nostack` option was already provided
+  --> $DIR/duplicate-options.rs:14:71
+   |
+LL |         asm!("", options(nostack, nostack), options(nostack), options(nostack));
+   |                                                                       ^^^^^^^ this option was already provided
+
+error: the `noreturn` option was already provided
+  --> $DIR/duplicate-options.rs:21:33
+   |
+LL |             options(att_syntax, noreturn),
+   |                                 ^^^^^^^^ this option was already provided
+
+error: the `nomem` option was already provided
+  --> $DIR/duplicate-options.rs:22:21
+   |
+LL |             options(nomem, nostack),
+   |                     ^^^^^ this option was already provided
+
+error: the `noreturn` option was already provided
+  --> $DIR/duplicate-options.rs:23:21
+   |
+LL |             options(noreturn),
+   |                     ^^^^^^^^ this option was already provided
+
+error: the `att_syntax` option was already provided
+  --> $DIR/duplicate-options.rs:28:37
+   |
+LL | global_asm!("", options(att_syntax, att_syntax));
+   |                                     ^^^^^^^^^^ this option was already provided
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/asm/x86_64/interpolated-idents.rs b/src/test/ui/asm/x86_64/interpolated-idents.rs
new file mode 100644 (file)
index 0000000..f4cb749
--- /dev/null
@@ -0,0 +1,24 @@
+// only-x86_64
+
+#![feature(asm)]
+
+macro_rules! m {
+    ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
+     $pure:ident $nomem:ident $readonly:ident $preserves_flags:ident
+     $noreturn:ident $nostack:ident $att_syntax:ident $options:ident) => {
+        unsafe {
+            asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+            //~^ ERROR asm outputs are not allowed with the `noreturn` option
+            const x, sym x,
+            $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+            //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
+            //~| ERROR the `pure` and `noreturn` options are mutually exclusive
+        }
+    };
+}
+
+fn main() {
+    m!(in out lateout inout inlateout const sym
+       pure nomem readonly preserves_flags
+       noreturn nostack att_syntax options);
+}
diff --git a/src/test/ui/asm/x86_64/interpolated-idents.stderr b/src/test/ui/asm/x86_64/interpolated-idents.stderr
new file mode 100644 (file)
index 0000000..5de8d20
--- /dev/null
@@ -0,0 +1,51 @@
+error: the `nomem` and `readonly` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |____________________________________________- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: the `pure` and `noreturn` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |____________________________________________- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm outputs are not allowed with the `noreturn` option
+  --> $DIR/interpolated-idents.rs:10:32
+   |
+LL |               asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+   |                                  ^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^^^^^^^^
+...
+LL |       m!(in out lateout inout inlateout const sym
+   |  _____-
+   | |_____|
+   | |_____|
+   | |_____|
+   | |
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |                                            -
+   | |____________________________________________|
+   | |____________________________________________in this macro invocation
+   | |____________________________________________in this macro invocation
+   | |____________________________________________in this macro invocation
+   |                                              in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/asm/x86_64/issue-82869.rs b/src/test/ui/asm/x86_64/issue-82869.rs
new file mode 100644 (file)
index 0000000..a8e688c
--- /dev/null
@@ -0,0 +1,23 @@
+// only-x86_64
+// Make sure rustc doesn't ICE on asm! for a foreign architecture.
+
+#![feature(asm)]
+#![crate_type = "rlib"]
+
+pub unsafe fn aarch64(a: f64, b: f64) -> f64 {
+    let c;
+    asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
+        || {};
+        b
+    });
+    //~^^^^ invalid register class
+    //~^^^^^ invalid register class
+    //~^^^^^^ invalid register
+    c
+}
+
+pub unsafe fn x86(a: f64, b: f64) -> f64 {
+    let c;
+    asm!("addsd {}, {}, xmm0", out(xmm_reg) c, in(xmm_reg) a, in("xmm0") b);
+    c
+}
diff --git a/src/test/ui/asm/x86_64/issue-82869.stderr b/src/test/ui/asm/x86_64/issue-82869.stderr
new file mode 100644 (file)
index 0000000..d05714e
--- /dev/null
@@ -0,0 +1,24 @@
+error: invalid register class `vreg`: unknown register class
+  --> $DIR/issue-82869.rs:9:32
+   |
+LL |     asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
+   |                                ^^^^^^^^^^^
+
+error: invalid register class `vreg`: unknown register class
+  --> $DIR/issue-82869.rs:9:45
+   |
+LL |     asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
+   |                                             ^^^^^^^^^^
+
+error: invalid register `d0`: unknown register
+  --> $DIR/issue-82869.rs:9:57
+   |
+LL |       asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") {
+   |  _________________________________________________________^
+LL | |         || {};
+LL | |         b
+LL | |     });
+   | |_____^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/asm/x86_64/parse-error.rs b/src/test/ui/asm/x86_64/parse-error.rs
new file mode 100644 (file)
index 0000000..fa14c52
--- /dev/null
@@ -0,0 +1,135 @@
+// only-x86_64
+
+#![feature(asm, global_asm)]
+
+fn main() {
+    let mut foo = 0;
+    let mut bar = 0;
+    unsafe {
+        asm!();
+        //~^ ERROR requires at least a template string argument
+        asm!(foo);
+        //~^ ERROR asm template must be a string literal
+        asm!("{}" foo);
+        //~^ ERROR expected token: `,`
+        asm!("{}", foo);
+        //~^ ERROR expected operand, clobber_abi, options, or additional template string
+        asm!("{}", in foo);
+        //~^ ERROR expected `(`, found `foo`
+        asm!("{}", in(reg foo));
+        //~^ ERROR expected `)`, found `foo`
+        asm!("{}", in(reg));
+        //~^ ERROR expected expression, found end of macro arguments
+        asm!("{}", inout(=) foo => bar);
+        //~^ ERROR expected register class or explicit register
+        asm!("{}", inout(reg) foo =>);
+        //~^ ERROR expected expression, found end of macro arguments
+        asm!("{}", in(reg) foo => bar);
+        //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
+        asm!("{}", sym foo + bar);
+        //~^ ERROR argument to `sym` must be a path expression
+        asm!("", options(foo));
+        //~^ ERROR expected one of
+        asm!("", options(nomem foo));
+        //~^ ERROR expected one of
+        asm!("", options(nomem, foo));
+        //~^ ERROR expected one of
+        asm!("{}", options(), const foo);
+        //~^ ERROR arguments are not allowed after options
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", clobber_abi(foo));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi("C" foo));
+        //~^ ERROR expected `)`, found `foo`
+        asm!("", clobber_abi("C", foo));
+        //~^ ERROR expected `)`, found `,`
+        asm!("{}", clobber_abi("C"), const foo);
+        //~^ ERROR arguments are not allowed after clobber_abi
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", options(), clobber_abi("C"));
+        //~^ ERROR clobber_abi is not allowed after options
+        asm!("{}", options(), clobber_abi("C"), const foo);
+        //~^ ERROR clobber_abi is not allowed after options
+        asm!("", clobber_abi("C"), clobber_abi("C"));
+        //~^ ERROR clobber_abi specified multiple times
+        asm!("{a}", a = const foo, a = const bar);
+        //~^ ERROR duplicate argument named `a`
+        //~^^ ERROR argument never used
+        //~^^^ ERROR attempt to use a non-constant value in a constant
+        //~^^^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", a = in("eax") foo);
+        //~^ ERROR explicit register arguments cannot have names
+        asm!("{a}", in("eax") foo, a = const bar);
+        //~^ ERROR named arguments cannot follow explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("{a}", in("eax") foo, a = const bar);
+        //~^ ERROR named arguments cannot follow explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("{1}", in("eax") foo, const bar);
+        //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+        asm!("", options(), "");
+        //~^ ERROR expected one of
+        asm!("{}", in(reg) foo, "{}", out(reg) foo);
+        //~^ ERROR expected one of
+        asm!(format!("{{{}}}", 0), in(reg) foo);
+        //~^ ERROR asm template must be a string literal
+        asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
+        //~^ ERROR asm template must be a string literal
+        asm!("{}", in(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inlateout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+    }
+}
+
+const FOO: i32 = 1;
+const BAR: i32 = 2;
+global_asm!();
+//~^ ERROR requires at least a template string argument
+global_asm!(FOO);
+//~^ ERROR asm template must be a string literal
+global_asm!("{}" FOO);
+//~^ ERROR expected token: `,`
+global_asm!("{}", FOO);
+//~^ ERROR expected operand, options, or additional template string
+global_asm!("{}", const);
+//~^ ERROR expected expression, found end of macro arguments
+global_asm!("{}", const(reg) FOO);
+//~^ ERROR expected one of
+global_asm!("", options(FOO));
+//~^ ERROR expected one of
+global_asm!("", options(nomem FOO));
+//~^ ERROR expected one of
+global_asm!("", options(nomem, FOO));
+//~^ ERROR expected one of
+global_asm!("{}", options(), const FOO);
+//~^ ERROR arguments are not allowed after options
+global_asm!("", clobber_abi(FOO));
+//~^ ERROR expected string literal
+global_asm!("", clobber_abi("C" FOO));
+//~^ ERROR expected `)`, found `FOO`
+global_asm!("", clobber_abi("C", FOO));
+//~^ ERROR expected `)`, found `,`
+global_asm!("{}", clobber_abi("C"), const FOO);
+//~^ ERROR arguments are not allowed after clobber_abi
+//~^^ ERROR `clobber_abi` cannot be used with `global_asm!`
+global_asm!("", options(), clobber_abi("C"));
+//~^ ERROR clobber_abi is not allowed after options
+global_asm!("{}", options(), clobber_abi("C"), const FOO);
+//~^ ERROR clobber_abi is not allowed after options
+global_asm!("", clobber_abi("C"), clobber_abi("C"));
+//~^ ERROR clobber_abi specified multiple times
+global_asm!("{a}", a = const FOO, a = const BAR);
+//~^ ERROR duplicate argument named `a`
+//~^^ ERROR argument never used
+global_asm!("", options(), "");
+//~^ ERROR expected one of
+global_asm!("{}", const FOO, "{}", const FOO);
+//~^ ERROR expected one of
+global_asm!(format!("{{{}}}", 0), const FOO);
+//~^ ERROR asm template must be a string literal
+global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
+//~^ ERROR asm template must be a string literal
diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr
new file mode 100644 (file)
index 0000000..78d342c
--- /dev/null
@@ -0,0 +1,462 @@
+error: requires at least a template string argument
+  --> $DIR/parse-error.rs:9:9
+   |
+LL |         asm!();
+   |         ^^^^^^^
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:11:14
+   |
+LL |         asm!(foo);
+   |              ^^^
+
+error: expected token: `,`
+  --> $DIR/parse-error.rs:13:19
+   |
+LL |         asm!("{}" foo);
+   |                   ^^^ expected `,`
+
+error: expected operand, clobber_abi, options, or additional template string
+  --> $DIR/parse-error.rs:15:20
+   |
+LL |         asm!("{}", foo);
+   |                    ^^^ expected operand, clobber_abi, options, or additional template string
+
+error: expected `(`, found `foo`
+  --> $DIR/parse-error.rs:17:23
+   |
+LL |         asm!("{}", in foo);
+   |                       ^^^ expected `(`
+
+error: expected `)`, found `foo`
+  --> $DIR/parse-error.rs:19:27
+   |
+LL |         asm!("{}", in(reg foo));
+   |                           ^^^ expected `)`
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:21:27
+   |
+LL |         asm!("{}", in(reg));
+   |                           ^ expected expression
+
+error: expected register class or explicit register
+  --> $DIR/parse-error.rs:23:26
+   |
+LL |         asm!("{}", inout(=) foo => bar);
+   |                          ^
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:25:37
+   |
+LL |         asm!("{}", inout(reg) foo =>);
+   |                                     ^ expected expression
+
+error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
+  --> $DIR/parse-error.rs:27:32
+   |
+LL |         asm!("{}", in(reg) foo => bar);
+   |                                ^^ expected one of 7 possible tokens
+
+error: argument to `sym` must be a path expression
+  --> $DIR/parse-error.rs:29:24
+   |
+LL |         asm!("{}", sym foo + bar);
+   |                        ^^^^^^^^^
+
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
+  --> $DIR/parse-error.rs:31:26
+   |
+LL |         asm!("", options(foo));
+   |                          ^^^ expected one of 9 possible tokens
+
+error: expected one of `)` or `,`, found `foo`
+  --> $DIR/parse-error.rs:33:32
+   |
+LL |         asm!("", options(nomem foo));
+   |                                ^^^ expected one of `)` or `,`
+
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
+  --> $DIR/parse-error.rs:35:33
+   |
+LL |         asm!("", options(nomem, foo));
+   |                                 ^^^ expected one of 9 possible tokens
+
+error: arguments are not allowed after options
+  --> $DIR/parse-error.rs:37:31
+   |
+LL |         asm!("{}", options(), const foo);
+   |                    ---------  ^^^^^^^^^ argument
+   |                    |
+   |                    previous options
+
+error: expected string literal
+  --> $DIR/parse-error.rs:40:30
+   |
+LL |         asm!("", clobber_abi(foo));
+   |                              ^^^ not a string literal
+
+error: expected `)`, found `foo`
+  --> $DIR/parse-error.rs:42:34
+   |
+LL |         asm!("", clobber_abi("C" foo));
+   |                                  ^^^ expected `)`
+
+error: expected `)`, found `,`
+  --> $DIR/parse-error.rs:44:33
+   |
+LL |         asm!("", clobber_abi("C", foo));
+   |                                 ^ expected `)`
+
+error: arguments are not allowed after clobber_abi
+  --> $DIR/parse-error.rs:46:38
+   |
+LL |         asm!("{}", clobber_abi("C"), const foo);
+   |                    ----------------  ^^^^^^^^^ argument
+   |                    |
+   |                    clobber_abi
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:49:29
+   |
+LL |         asm!("", options(), clobber_abi("C"));
+   |                  ---------  ^^^^^^^^^^^^^^^^
+   |                  |
+   |                  options
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:51:31
+   |
+LL |         asm!("{}", options(), clobber_abi("C"), const foo);
+   |                    ---------  ^^^^^^^^^^^^^^^^
+   |                    |
+   |                    options
+
+error: clobber_abi specified multiple times
+  --> $DIR/parse-error.rs:53:36
+   |
+LL |         asm!("", clobber_abi("C"), clobber_abi("C"));
+   |                  ----------------  ^^^^^^^^^^^^^^^^
+   |                  |
+   |                  clobber_abi previously specified here
+
+error: duplicate argument named `a`
+  --> $DIR/parse-error.rs:55:36
+   |
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                     -------------  ^^^^^^^^^^^^^ duplicate argument
+   |                     |
+   |                     previously here
+
+error: argument never used
+  --> $DIR/parse-error.rs:55:36
+   |
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                                    ^^^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
+
+error: explicit register arguments cannot have names
+  --> $DIR/parse-error.rs:60:18
+   |
+LL |         asm!("", a = in("eax") foo);
+   |                  ^^^^^^^^^^^^^^^^^
+
+error: named arguments cannot follow explicit register arguments
+  --> $DIR/parse-error.rs:62:36
+   |
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                     -------------  ^^^^^^^^^^^^^ named argument
+   |                     |
+   |                     explicit register argument
+
+error: named arguments cannot follow explicit register arguments
+  --> $DIR/parse-error.rs:65:36
+   |
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                     -------------  ^^^^^^^^^^^^^ named argument
+   |                     |
+   |                     explicit register argument
+
+error: positional arguments cannot follow named arguments or explicit register arguments
+  --> $DIR/parse-error.rs:68:36
+   |
+LL |         asm!("{1}", in("eax") foo, const bar);
+   |                     -------------  ^^^^^^^^^ positional argument
+   |                     |
+   |                     explicit register argument
+
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
+  --> $DIR/parse-error.rs:71:29
+   |
+LL |         asm!("", options(), "");
+   |                             ^^ expected one of 9 possible tokens
+
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
+  --> $DIR/parse-error.rs:73:33
+   |
+LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
+   |                                 ^^^^ expected one of 9 possible tokens
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:75:14
+   |
+LL |         asm!(format!("{{{}}}", 0), in(reg) foo);
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:77:21
+   |
+LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
+   |                     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:79:28
+   |
+LL |         asm!("{}", in(reg) _);
+   |                            ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:81:31
+   |
+LL |         asm!("{}", inout(reg) _);
+   |                               ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:83:35
+   |
+LL |         asm!("{}", inlateout(reg) _);
+   |                                   ^
+
+error: requires at least a template string argument
+  --> $DIR/parse-error.rs:90:1
+   |
+LL | global_asm!();
+   | ^^^^^^^^^^^^^^
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:92:13
+   |
+LL | global_asm!(FOO);
+   |             ^^^
+
+error: expected token: `,`
+  --> $DIR/parse-error.rs:94:18
+   |
+LL | global_asm!("{}" FOO);
+   |                  ^^^ expected `,`
+
+error: expected operand, options, or additional template string
+  --> $DIR/parse-error.rs:96:19
+   |
+LL | global_asm!("{}", FOO);
+   |                   ^^^ expected operand, options, or additional template string
+
+error: expected expression, found end of macro arguments
+  --> $DIR/parse-error.rs:98:24
+   |
+LL | global_asm!("{}", const);
+   |                        ^ expected expression
+
+error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
+  --> $DIR/parse-error.rs:100:30
+   |
+LL | global_asm!("{}", const(reg) FOO);
+   |                              ^^^ expected one of `,`, `.`, `?`, or an operator
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
+  --> $DIR/parse-error.rs:102:25
+   |
+LL | global_asm!("", options(FOO));
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/parse-error.rs:104:25
+   |
+LL | global_asm!("", options(nomem FOO));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+  --> $DIR/parse-error.rs:106:25
+   |
+LL | global_asm!("", options(nomem, FOO));
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+
+error: arguments are not allowed after options
+  --> $DIR/parse-error.rs:108:30
+   |
+LL | global_asm!("{}", options(), const FOO);
+   |                   ---------  ^^^^^^^^^ argument
+   |                   |
+   |                   previous options
+
+error: expected string literal
+  --> $DIR/parse-error.rs:110:29
+   |
+LL | global_asm!("", clobber_abi(FOO));
+   |                             ^^^ not a string literal
+
+error: expected `)`, found `FOO`
+  --> $DIR/parse-error.rs:112:33
+   |
+LL | global_asm!("", clobber_abi("C" FOO));
+   |                                 ^^^ expected `)`
+
+error: expected `)`, found `,`
+  --> $DIR/parse-error.rs:114:32
+   |
+LL | global_asm!("", clobber_abi("C", FOO));
+   |                                ^ expected `)`
+
+error: arguments are not allowed after clobber_abi
+  --> $DIR/parse-error.rs:116:37
+   |
+LL | global_asm!("{}", clobber_abi("C"), const FOO);
+   |                   ----------------  ^^^^^^^^^ argument
+   |                   |
+   |                   clobber_abi
+
+error: `clobber_abi` cannot be used with `global_asm!`
+  --> $DIR/parse-error.rs:116:19
+   |
+LL | global_asm!("{}", clobber_abi("C"), const FOO);
+   |                   ^^^^^^^^^^^^^^^^
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:119:28
+   |
+LL | global_asm!("", options(), clobber_abi("C"));
+   |                 ---------  ^^^^^^^^^^^^^^^^
+   |                 |
+   |                 options
+
+error: clobber_abi is not allowed after options
+  --> $DIR/parse-error.rs:121:30
+   |
+LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
+   |                   ---------  ^^^^^^^^^^^^^^^^
+   |                   |
+   |                   options
+
+error: clobber_abi specified multiple times
+  --> $DIR/parse-error.rs:123:35
+   |
+LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
+   |                 ----------------  ^^^^^^^^^^^^^^^^
+   |                 |
+   |                 clobber_abi previously specified here
+
+error: duplicate argument named `a`
+  --> $DIR/parse-error.rs:125:35
+   |
+LL | global_asm!("{a}", a = const FOO, a = const BAR);
+   |                    -------------  ^^^^^^^^^^^^^ duplicate argument
+   |                    |
+   |                    previously here
+
+error: argument never used
+  --> $DIR/parse-error.rs:125:35
+   |
+LL | global_asm!("{a}", a = const FOO, a = const BAR);
+   |                                   ^^^^^^^^^^^^^ argument never used
+   |
+   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
+
+error: expected one of `clobber_abi`, `const`, or `options`, found `""`
+  --> $DIR/parse-error.rs:128:28
+   |
+LL | global_asm!("", options(), "");
+   |                            ^^ expected one of `clobber_abi`, `const`, or `options`
+
+error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
+  --> $DIR/parse-error.rs:130:30
+   |
+LL | global_asm!("{}", const FOO, "{}", const FOO);
+   |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:132:13
+   |
+LL | global_asm!(format!("{{{}}}", 0), const FOO);
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm template must be a string literal
+  --> $DIR/parse-error.rs:134:20
+   |
+LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
+   |                    ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:37:37
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{}", options(), const foo);
+   |                                     ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:46:44
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{}", clobber_abi("C"), const foo);
+   |                                            ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:55:31
+   |
+LL |     let mut foo = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const foo`
+...
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                               ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:55:46
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", a = const foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:62:46
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:65:46
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/parse-error.rs:68:42
+   |
+LL |     let mut bar = 0;
+   |      ---------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{1}", in("eax") foo, const bar);
+   |                                          ^^^ non-constant value
+
+error: aborting due to 66 previous errors
+
+For more information about this error, try `rustc --explain E0435`.
diff --git a/src/test/ui/asm/x86_64/srcloc.rs b/src/test/ui/asm/x86_64/srcloc.rs
new file mode 100644 (file)
index 0000000..ed8cefc
--- /dev/null
@@ -0,0 +1,124 @@
+// min-llvm-version: 10.0.1
+// only-x86_64
+// build-fail
+// compile-flags: -Ccodegen-units=1
+#![feature(asm)]
+
+// Checks that inline asm errors are mapped to the correct line in the source code.
+
+fn main() {
+    unsafe {
+        asm!("invalid_instruction");
+        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("
+            invalid_instruction
+        ");
+        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(r#"
+            invalid_instruction
+        "#);
+        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("
+            mov eax, eax
+            invalid_instruction
+            mov eax, eax
+        ");
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(r#"
+            mov eax, eax
+            invalid_instruction
+            mov eax, eax
+        "#);
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(concat!("invalid", "_", "instruction"));
+        //~^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
+        //~^ WARN: scale factor without index register is ignored
+
+        asm!(
+            "invalid_instruction",
+        );
+        //~^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(
+            "mov eax, eax",
+            "invalid_instruction",
+            "mov eax, eax",
+        );
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(
+            "mov eax, eax\n",
+            "invalid_instruction",
+            "mov eax, eax",
+        );
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(
+            "mov eax, eax",
+            concat!("invalid", "_", "instruction"),
+            "mov eax, eax",
+        );
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        asm!(
+            concat!("mov eax", ", ", "eax"),
+            concat!("invalid", "_", "instruction"),
+            concat!("mov eax", ", ", "eax"),
+        );
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction'
+
+        // Make sure template strings get separated
+        asm!(
+            "invalid_instruction1",
+            "invalid_instruction2",
+        );
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
+        //~^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2",
+            ),
+        );
+        //~^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
+        //~^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2",
+            ),
+            concat!(
+                "invalid", "_", "instruction3", "\n",
+                "invalid", "_", "instruction4",
+            ),
+        );
+        //~^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
+        //~^^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
+        //~^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction3'
+        //~^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction4'
+
+        asm!(
+            concat!(
+                "invalid", "_", "instruction1", "\n",
+                "invalid", "_", "instruction2", "\n",
+            ),
+            concat!(
+                "invalid", "_", "instruction3", "\n",
+                "invalid", "_", "instruction4", "\n",
+            ),
+        );
+        //~^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction1'
+        //~^^^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction2'
+        //~^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction3'
+        //~^^^^^^^^ ERROR: invalid instruction mnemonic 'invalid_instruction4'
+    }
+}
diff --git a/src/test/ui/asm/x86_64/srcloc.stderr b/src/test/ui/asm/x86_64/srcloc.stderr
new file mode 100644 (file)
index 0000000..b62c894
--- /dev/null
@@ -0,0 +1,290 @@
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:11:15
+   |
+LL |         asm!("invalid_instruction");
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:15:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:20:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:26:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:33:13
+   |
+LL |             invalid_instruction
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:13
+   |
+LL |             invalid_instruction
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:38:14
+   |
+LL |         asm!(concat!("invalid", "_", "instruction"));
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+warning: scale factor without index register is ignored
+  --> $DIR/srcloc.rs:41:15
+   |
+LL |         asm!("movaps %xmm3, (%esi, 2)", options(att_syntax));
+   |               ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:23
+   |
+LL |     movaps %xmm3, (%esi, 2)
+   |                          ^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:45:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:51:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:58:14
+   |
+LL |             "invalid_instruction",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:65:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction'
+  --> $DIR/srcloc.rs:72:13
+   |
+LL |             concat!("invalid", "_", "instruction"),
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:79:14
+   |
+LL |             "invalid_instruction1",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:80:14
+   |
+LL |             "invalid_instruction2",
+   |              ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:86:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:86:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:95:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:95:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction3'
+  --> $DIR/srcloc.rs:99:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:4:1
+   |
+LL | invalid_instruction3
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction4'
+  --> $DIR/srcloc.rs:99:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction4
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction1'
+  --> $DIR/srcloc.rs:110:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:2:2
+   |
+LL |     invalid_instruction1
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction2'
+  --> $DIR/srcloc.rs:110:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:3:1
+   |
+LL | invalid_instruction2
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction3'
+  --> $DIR/srcloc.rs:114:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:5:1
+   |
+LL | invalid_instruction3
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid instruction mnemonic 'invalid_instruction4'
+  --> $DIR/srcloc.rs:114:13
+   |
+LL |             concat!(
+   |             ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:6:1
+   |
+LL | invalid_instruction4
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 23 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/asm/x86_64/sym.rs b/src/test/ui/asm/x86_64/sym.rs
new file mode 100644 (file)
index 0000000..634ef01
--- /dev/null
@@ -0,0 +1,80 @@
+// min-llvm-version: 10.0.1
+// only-x86_64
+// only-linux
+// run-pass
+
+#![feature(asm, thread_local)]
+
+extern "C" fn f1() -> i32 {
+    111
+}
+
+// The compiler will generate a shim to hide the caller location parameter.
+#[track_caller]
+fn f2() -> i32 {
+    222
+}
+
+macro_rules! call {
+    ($func:path) => {
+        unsafe {
+            let result: i32;
+            asm!("call {}", sym $func,
+                out("rax") result,
+                out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
+                out("r8") _, out("r9") _, out("r10") _, out("r11") _,
+                out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
+                out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
+                out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
+                out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
+            );
+            result
+        }
+    }
+}
+
+macro_rules! static_addr {
+    ($s:expr) => {
+        unsafe {
+            let result: *const u32;
+            // LEA performs a RIP-relative address calculation and returns the address
+            asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
+            result
+        }
+    }
+}
+macro_rules! static_tls_addr {
+    ($s:expr) => {
+        unsafe {
+            let result: *const u32;
+            asm!(
+                "
+                    # Load TLS base address
+                    mov {out}, qword ptr fs:[0]
+                    # Calculate the address of sym in the TLS block. The @tpoff
+                    # relocation gives the offset of the symbol from the start
+                    # of the TLS block.
+                    lea {out}, [{out} + {sym}@tpoff]
+                ",
+                out = out(reg) result,
+                sym = sym $s
+            );
+            result
+        }
+    }
+}
+
+static S1: u32 = 111;
+#[thread_local]
+static S2: u32 = 222;
+
+fn main() {
+    assert_eq!(call!(f1), 111);
+    assert_eq!(call!(f2), 222);
+    assert_eq!(static_addr!(S1), &S1 as *const u32);
+    assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
+    std::thread::spawn(|| {
+        assert_eq!(static_addr!(S1), &S1 as *const u32);
+        assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
+    }).join().unwrap();
+}
diff --git a/src/test/ui/asm/x86_64/type-check-2.rs b/src/test/ui/asm/x86_64/type-check-2.rs
new file mode 100644 (file)
index 0000000..2311f86
--- /dev/null
@@ -0,0 +1,80 @@
+// only-x86_64
+
+#![feature(asm, repr_simd, never_type)]
+
+#[repr(simd)]
+struct SimdNonCopy(f32, f32, f32, f32);
+
+fn main() {
+    unsafe {
+        // Inputs must be initialized
+
+        let x: u64;
+        asm!("{}", in(reg) x);
+        //~^ ERROR use of possibly-uninitialized variable: `x`
+        let mut y: u64;
+        asm!("{}", inout(reg) y);
+        //~^ ERROR use of possibly-uninitialized variable: `y`
+        let _ = y;
+
+        // Outputs require mutable places
+
+        let v: Vec<u64> = vec![0, 1, 2];
+        asm!("{}", in(reg) v[0]);
+        asm!("{}", out(reg) v[0]);
+        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
+        asm!("{}", inout(reg) v[0]);
+        //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
+
+        // Sym operands must point to a function or static
+
+        const C: i32 = 0;
+        static S: i32 = 0;
+        asm!("{}", sym S);
+        asm!("{}", sym main);
+        asm!("{}", sym C);
+        //~^ ERROR asm `sym` operand must point to a fn or static
+        asm!("{}", sym x);
+        //~^ ERROR asm `sym` operand must point to a fn or static
+
+        // Register operands must be Copy
+
+        asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+        //~^ ERROR arguments for inline assembly must be copyable
+
+        // Register operands must be integers, floats, SIMD vectors, pointers or
+        // function pointers.
+
+        asm!("{}", in(reg) 0i64);
+        asm!("{}", in(reg) 0f64);
+        asm!("{}", in(xmm_reg) std::arch::x86_64::_mm_setzero_ps());
+        asm!("{}", in(reg) 0 as *const u8);
+        asm!("{}", in(reg) 0 as *mut u8);
+        asm!("{}", in(reg) main as fn());
+        asm!("{}", in(reg) |x: i32| x);
+        //~^ ERROR cannot use value of type
+        asm!("{}", in(reg) vec![0]);
+        //~^ ERROR cannot use value of type `Vec<i32>` for inline assembly
+        asm!("{}", in(reg) (1, 2, 3));
+        //~^ ERROR cannot use value of type `(i32, i32, i32)` for inline assembly
+        asm!("{}", in(reg) [1, 2, 3]);
+        //~^ ERROR cannot use value of type `[i32; 3]` for inline assembly
+
+        // Register inputs (but not outputs) allow references and function types
+
+        let mut f = main;
+        let mut r = &mut 0;
+        asm!("{}", in(reg) f);
+        asm!("{}", inout(reg) f);
+        //~^ ERROR cannot use value of type `fn() {main}` for inline assembly
+        asm!("{}", in(reg) r);
+        asm!("{}", inout(reg) r);
+        //~^ ERROR cannot use value of type `&mut i32` for inline assembly
+        let _ = (f, r);
+
+        // Type checks ignore never type
+
+        let u: ! = unreachable!();
+        asm!("{}", in(reg) u);
+    }
+}
diff --git a/src/test/ui/asm/x86_64/type-check-2.stderr b/src/test/ui/asm/x86_64/type-check-2.stderr
new file mode 100644 (file)
index 0000000..b82a0b8
--- /dev/null
@@ -0,0 +1,103 @@
+error: arguments for inline assembly must be copyable
+  --> $DIR/type-check-2.rs:42:32
+   |
+LL |         asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `SimdNonCopy` does not implement the Copy trait
+
+error: cannot use value of type `[closure@$DIR/type-check-2.rs:54:28: 54:38]` for inline assembly
+  --> $DIR/type-check-2.rs:54:28
+   |
+LL |         asm!("{}", in(reg) |x: i32| x);
+   |                            ^^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `Vec<i32>` for inline assembly
+  --> $DIR/type-check-2.rs:56:28
+   |
+LL |         asm!("{}", in(reg) vec![0]);
+   |                            ^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot use value of type `(i32, i32, i32)` for inline assembly
+  --> $DIR/type-check-2.rs:58:28
+   |
+LL |         asm!("{}", in(reg) (1, 2, 3));
+   |                            ^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `[i32; 3]` for inline assembly
+  --> $DIR/type-check-2.rs:60:28
+   |
+LL |         asm!("{}", in(reg) [1, 2, 3]);
+   |                            ^^^^^^^^^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `fn() {main}` for inline assembly
+  --> $DIR/type-check-2.rs:68:31
+   |
+LL |         asm!("{}", inout(reg) f);
+   |                               ^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: cannot use value of type `&mut i32` for inline assembly
+  --> $DIR/type-check-2.rs:71:31
+   |
+LL |         asm!("{}", inout(reg) r);
+   |                               ^
+   |
+   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
+
+error: asm `sym` operand must point to a fn or static
+  --> $DIR/type-check-2.rs:35:24
+   |
+LL |         asm!("{}", sym C);
+   |                        ^
+
+error: asm `sym` operand must point to a fn or static
+  --> $DIR/type-check-2.rs:37:24
+   |
+LL |         asm!("{}", sym x);
+   |                        ^
+
+error[E0381]: use of possibly-uninitialized variable: `x`
+  --> $DIR/type-check-2.rs:13:28
+   |
+LL |         asm!("{}", in(reg) x);
+   |                            ^ use of possibly-uninitialized `x`
+
+error[E0381]: use of possibly-uninitialized variable: `y`
+  --> $DIR/type-check-2.rs:16:9
+   |
+LL |         asm!("{}", inout(reg) y);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
+
+error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
+  --> $DIR/type-check-2.rs:24:29
+   |
+LL |         let v: Vec<u64> = vec![0, 1, 2];
+   |             - help: consider changing this to be mutable: `mut v`
+LL |         asm!("{}", in(reg) v[0]);
+LL |         asm!("{}", out(reg) v[0]);
+   |                             ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
+  --> $DIR/type-check-2.rs:26:31
+   |
+LL |         let v: Vec<u64> = vec![0, 1, 2];
+   |             - help: consider changing this to be mutable: `mut v`
+...
+LL |         asm!("{}", inout(reg) v[0]);
+   |                               ^ cannot borrow as mutable
+
+error: aborting due to 13 previous errors
+
+Some errors have detailed explanations: E0381, E0596.
+For more information about an error, try `rustc --explain E0381`.
diff --git a/src/test/ui/asm/x86_64/type-check-3.rs b/src/test/ui/asm/x86_64/type-check-3.rs
new file mode 100644 (file)
index 0000000..c2c1885
--- /dev/null
@@ -0,0 +1,89 @@
+// only-x86_64
+// compile-flags: -C target-feature=+avx512f
+
+#![feature(asm, global_asm)]
+
+use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps};
+
+fn main() {
+    unsafe {
+        // Types must be listed in the register class.
+
+        asm!("{}", in(reg) 0i128);
+        //~^ ERROR type `i128` cannot be used with this register class
+        asm!("{}", in(reg) _mm_setzero_ps());
+        //~^ ERROR type `__m128` cannot be used with this register class
+        asm!("{}", in(reg) _mm256_setzero_ps());
+        //~^ ERROR type `__m256` cannot be used with this register class
+        asm!("{}", in(xmm_reg) 0u8);
+        //~^ ERROR type `u8` cannot be used with this register class
+        asm!("{:e}", in(reg) 0i32);
+        asm!("{}", in(xmm_reg) 0i32);
+        asm!("{:e}", in(reg) 0f32);
+        asm!("{}", in(xmm_reg) 0f32);
+        asm!("{}", in(xmm_reg) _mm_setzero_ps());
+        asm!("{:x}", in(ymm_reg) _mm_setzero_ps());
+        asm!("{}", in(kreg) 0u16);
+        asm!("{}", in(kreg) 0u64);
+        //~^ ERROR `avx512bw` target feature is not enabled
+
+        // Template modifier suggestions for sub-registers
+
+        asm!("{0} {0}", in(reg) 0i16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{0} {0:x}", in(reg) 0i16);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(reg) 0i32);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(reg) 0i64);
+        asm!("{}", in(ymm_reg) 0i64);
+        //~^ WARN formatting may not be suitable for sub-register argument
+        asm!("{}", in(ymm_reg) _mm256_setzero_ps());
+        asm!("{:l}", in(reg) 0i16);
+        asm!("{:l}", in(reg) 0i32);
+        asm!("{:l}", in(reg) 0i64);
+        asm!("{:x}", in(ymm_reg) 0i64);
+        asm!("{:x}", in(ymm_reg) _mm256_setzero_ps());
+
+        // Suggest different register class for type
+
+        asm!("{}", in(reg) 0i8);
+        //~^ ERROR type `i8` cannot be used with this register class
+        asm!("{}", in(reg_byte) 0i8);
+
+        // Split inout operands must have compatible types
+
+        let mut val_i16: i16;
+        let mut val_f32: f32;
+        let mut val_u32: u32;
+        let mut val_u64: u64;
+        let mut val_ptr: *mut u8;
+        asm!("{:r}", inout(reg) 0u16 => val_i16);
+        asm!("{:r}", inout(reg) 0u32 => val_f32);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:r}", inout(reg) 0u32 => val_ptr);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:r}", inout(reg) main => val_u32);
+        //~^ ERROR incompatible types for asm inout argument
+        asm!("{:r}", inout(reg) 0u64 => val_ptr);
+        asm!("{:r}", inout(reg) main => val_u64);
+    }
+}
+
+// Constants must be... constant
+
+static S: i32 = 1;
+const fn const_foo(x: i32) -> i32 {
+    x
+}
+const fn const_bar<T>(x: T) -> T {
+    x
+}
+global_asm!("{}", const S);
+//~^ ERROR constants cannot refer to statics
+global_asm!("{}", const const_foo(0));
+global_asm!("{}", const const_foo(S));
+//~^ ERROR constants cannot refer to statics
+global_asm!("{}", const const_bar(0));
+global_asm!("{}", const const_bar(S));
+//~^ ERROR constants cannot refer to statics
diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr
new file mode 100644 (file)
index 0000000..9f6989c
--- /dev/null
@@ -0,0 +1,143 @@
+error: type `i128` cannot be used with this register class
+  --> $DIR/type-check-3.rs:12:28
+   |
+LL |         asm!("{}", in(reg) 0i128);
+   |                            ^^^^^
+   |
+   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
+
+error: type `__m128` cannot be used with this register class
+  --> $DIR/type-check-3.rs:14:28
+   |
+LL |         asm!("{}", in(reg) _mm_setzero_ps());
+   |                            ^^^^^^^^^^^^^^^^
+   |
+   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
+
+error: type `__m256` cannot be used with this register class
+  --> $DIR/type-check-3.rs:16:28
+   |
+LL |         asm!("{}", in(reg) _mm256_setzero_ps());
+   |                            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
+
+error: type `u8` cannot be used with this register class
+  --> $DIR/type-check-3.rs:18:32
+   |
+LL |         asm!("{}", in(xmm_reg) 0u8);
+   |                                ^^^
+   |
+   = note: register class `xmm_reg` supports these types: i32, i64, f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+
+error: `avx512bw` target feature is not enabled
+  --> $DIR/type-check-3.rs:27:29
+   |
+LL |         asm!("{}", in(kreg) 0u64);
+   |                             ^^^^
+   |
+   = note: this is required to use type `u64` with register class `kreg`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:32:15
+   |
+LL |         asm!("{0} {0}", in(reg) 0i16);
+   |               ^^^ ^^^           ---- for this argument
+   |
+   = note: `#[warn(asm_sub_register)]` on by default
+   = help: use the `x` modifier to have the register formatted as `ax`
+   = help: or use the `r` modifier to keep the default formatting of `rax`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:34:15
+   |
+LL |         asm!("{0} {0:x}", in(reg) 0i16);
+   |               ^^^                 ---- for this argument
+   |
+   = help: use the `x` modifier to have the register formatted as `ax`
+   = help: or use the `r` modifier to keep the default formatting of `rax`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:36:15
+   |
+LL |         asm!("{}", in(reg) 0i32);
+   |               ^^           ---- for this argument
+   |
+   = help: use the `e` modifier to have the register formatted as `eax`
+   = help: or use the `r` modifier to keep the default formatting of `rax`
+
+warning: formatting may not be suitable for sub-register argument
+  --> $DIR/type-check-3.rs:39:15
+   |
+LL |         asm!("{}", in(ymm_reg) 0i64);
+   |               ^^               ---- for this argument
+   |
+   = help: use the `x` modifier to have the register formatted as `xmm0`
+   = help: or use the `y` modifier to keep the default formatting of `ymm0`
+
+error: type `i8` cannot be used with this register class
+  --> $DIR/type-check-3.rs:50:28
+   |
+LL |         asm!("{}", in(reg) 0i8);
+   |                            ^^^
+   |
+   = note: register class `reg` supports these types: i16, i32, i64, f32, f64
+   = help: consider using the `reg_byte` register class instead
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:62:33
+   |
+LL |         asm!("{:r}", inout(reg) 0u32 => val_f32);
+   |                                 ^^^^    ^^^^^^^ type `f32`
+   |                                 |
+   |                                 type `u32`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:64:33
+   |
+LL |         asm!("{:r}", inout(reg) 0u32 => val_ptr);
+   |                                 ^^^^    ^^^^^^^ type `*mut u8`
+   |                                 |
+   |                                 type `u32`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error: incompatible types for asm inout argument
+  --> $DIR/type-check-3.rs:66:33
+   |
+LL |         asm!("{:r}", inout(reg) main => val_u32);
+   |                                 ^^^^    ^^^^^^^ type `u32`
+   |                                 |
+   |                                 type `fn()`
+   |
+   = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:82:25
+   |
+LL | global_asm!("{}", const S);
+   |                         ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:85:35
+   |
+LL | global_asm!("{}", const const_foo(S));
+   |                                   ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error[E0013]: constants cannot refer to statics
+  --> $DIR/type-check-3.rs:88:35
+   |
+LL | global_asm!("{}", const const_bar(S));
+   |                                   ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error: aborting due to 12 previous errors; 4 warnings emitted
+
+For more information about this error, try `rustc --explain E0013`.
index ad5c6aed97c2c3ce7fb57c7215a839fc33b49a32..d854dce382fc47ea1591f9ea353f27092a708b97 100644 (file)
@@ -1,5 +1,5 @@
 // check-pass
-// compile-flags:-Cincremental=tmp/traits-assoc-type-macros
+// incremental
 
 // This test case makes sure that we can compile with incremental compilation
 // enabled when there are macros, traits, inheritance and associated types involved.
index 96ba2ee3b62b8c12ffd2875d792a988e67cfd271..05498ba63e9948305f8a699be193bcc41131e43b 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn pairwise_sub(mut t: Box<dyn DoubleEndedIterator<Item=isize>>) -> isize {
     let mut result = 0;
index 61c8c8c1594d3b80a6d2a36ffd1409460e7c00c9..2280154c7157ce4dbe3896635d42cb79755774fa 100644 (file)
@@ -1,5 +1,5 @@
 // edition:2018
-// compile-flags:-Cincremental=tmp/issue-72442
+// incremental
 
 use std::fs::File;
 use std::future::Future;
index 5313d1715c4835574c22bcddf63ff88cba76510c..6d6eff4864ee3663cc1c415d4d9304a25932e433 100644 (file)
@@ -1,5 +1,6 @@
 // check-pass
-// compile-flags: -Z query-dep-graph -C incremental=tmp/issue-64964
+// incremental
+// compile-flags: -Z query-dep-graph
 // edition:2018
 
 // Regression test for ICE related to `await`ing in a method + incr. comp. (#64964)
index 1dbf5db6c32ed9bdae77c7c18787f270c9d003db..df2ca025705d3955fae6c9b1a0d7333e29f39684 100644 (file)
@@ -6,7 +6,6 @@ async fn copy() -> Result<()>
 //~^ ERROR this enum takes 2 generic arguments
 {
     Ok(())
-    //~^ ERROR type annotations needed
 }
 
 fn main() { }
index ff46bcb8983b34399dfe17292ca7b4325f3a3bd3..45f5ec40cd758b08f914aabdce72e0d85bd7996f 100644 (file)
@@ -16,13 +16,6 @@ help: add missing generic argument
 LL | async fn copy() -> Result<(), E>
    |                             +++
 
-error[E0282]: type annotations needed
-  --> $DIR/issue-65159.rs:8:5
-   |
-LL |     Ok(())
-   |     ^^ cannot infer type for type parameter `E` declared on the enum `Result`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0107, E0282.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/attributes/extented-attribute-macro-error.rs b/src/test/ui/attributes/extented-attribute-macro-error.rs
new file mode 100644 (file)
index 0000000..f5f75f9
--- /dev/null
@@ -0,0 +1,8 @@
+// normalize-stderr-test: "couldn't read.*" -> "couldn't read the file"
+
+#![feature(extended_key_value_attributes)]
+#![doc = include_str!("../not_existing_file.md")]
+struct Documented {}
+//~^^ ERROR couldn't read
+
+fn main() {}
diff --git a/src/test/ui/attributes/extented-attribute-macro-error.stderr b/src/test/ui/attributes/extented-attribute-macro-error.stderr
new file mode 100644 (file)
index 0000000..e4deeac
--- /dev/null
@@ -0,0 +1,10 @@
+error: couldn't read the file
+  --> $DIR/extented-attribute-macro-error.rs:4:10
+   |
+LL | #![doc = include_str!("../not_existing_file.md")]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
index 03ca515265cb0915684b0a4d40c7048046e37e38..31e93ef54f26034ffdf2a558bbcc403c47fd4177 100644 (file)
@@ -17,16 +17,12 @@ LL | bug!();
 
 error: unexpected token: `{
     let res =
-        ::alloc::fmt::format(match match (&"u8",) {
-                                       (arg0,) =>
-                                       [::core::fmt::ArgumentV1::new(arg0,
-                                                                     ::core::fmt::Display::fmt)],
-                                   } {
-                                 ref args => unsafe {
-                                     ::core::fmt::Arguments::new_v1(&[""],
-                                                                    args)
-                                 }
-                             });
+        ::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
+                                                            &match (&"u8",) {
+                                                                 (arg0,) =>
+                                                                 [::core::fmt::ArgumentV1::new(arg0,
+                                                                                               ::core::fmt::Display::fmt)],
+                                                             }));
     res
 }.as_str()`
   --> $DIR/key-value-expansion.rs:48:23
index 77acfcd87cf75cdeaadf131592c211248c1181a2..8f6977cb55f25b06db7444c53432a4be153359ed 100644 (file)
@@ -30,13 +30,13 @@ error: malformed `register_attr` attribute input
   --> $DIR/register-attr-tool-fail.rs:4:1
    |
 LL | #![register_attr]
-   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_attr(attr1, attr2, ...)]`
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_attr(attr1, attr2, ...)]`
 
 error: malformed `register_tool` attribute input
   --> $DIR/register-attr-tool-fail.rs:5:1
    |
 LL | #![register_tool]
-   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_tool(tool1, tool2, ...)]`
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_tool(tool1, tool2, ...)]`
 
 error: aborting due to 6 previous errors
 
index f07a2c107ba457be042a38bfdab532329fb1d635..0fadc5c98277e92574c946aa17a2a504d9eea8cc 100644 (file)
@@ -1,23 +1,23 @@
-#![feature(box_syntax)]
-
 struct Clam {
     x: Box<isize>,
     y: Box<isize>,
 }
 
+
+
 struct Fish {
     a: Box<isize>,
 }
 
 fn main() {
-    let a: Clam = Clam{x: box 1, y: box 2};
-    let b: Clam = Clam{x: box 10, y: box 20};
+    let a: Clam = Clam{ x: Box::new(1), y: Box::new(2) };
+    let b: Clam = Clam{ x: Box::new(10), y: Box::new(20) };
     let z: isize = a.x + b.y;
     //~^ ERROR cannot add `Box<isize>` to `Box<isize>`
     println!("{}", z);
     assert_eq!(z, 21);
-    let forty: Fish = Fish{a: box 40};
-    let two: Fish = Fish{a: box 2};
+    let forty: Fish = Fish{ a: Box::new(40) };
+    let two: Fish = Fish{ a: Box::new(2) };
     let answer: isize = forty.a + two.a;
     //~^ ERROR cannot add `Box<isize>` to `Box<isize>`
     println!("{}", answer);
index fadb0784e75257eb35354fe9b7c7885ed67b710b..af747cc76e9a062700280cb4a75107a767277966 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait double {
     fn double(self: Box<Self>) -> usize;
@@ -11,6 +10,6 @@ fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x: Box<_> = box (box 3usize as Box<dyn double>);
+    let x: Box<_> = Box::new(Box::new(3usize) as Box<dyn double>);
     assert_eq!(x.double(), 6);
 }
index a218f85eba2c6cecf487d049c0735edb581dacbe..88a5140dc752bb8d3fc1cad5ec08d487aba206b3 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait double {
     fn double(self) -> usize;
@@ -15,6 +14,6 @@ fn double(self) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     assert_eq!(x.double(), 6);
 }
index 9fda3b2c09999c0056a3852e4df503e7b441af2b..3657e61d42534a99253362e9bfa559045e057dda 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait double {
     fn double(self: Box<Self>) -> usize;
@@ -11,6 +10,6 @@ fn double(self: Box<Box<usize>>) -> usize { **self * 2 }
 }
 
 pub fn main() {
-    let x: Box<Box<Box<Box<Box<_>>>>> = box box box box box 3;
+    let x: Box<Box<Box<Box<Box<_>>>>> = Box::new(Box::new(Box::new(Box::new(Box::new(3)))));
     assert_eq!(x.double(), 6);
 }
index f53dc8d1032bff65db3304b5657e1365960975ff..ed86b31b8bbed626443bbc947368c3296ddb8a18 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait double {
     fn double(self: Box<Self>) -> usize;
@@ -11,6 +10,6 @@ fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x: Box<Box<_>> = box box 3;
+    let x: Box<Box<_>> = Box::new(Box::new(3));
     assert_eq!(x.double(), 6);
 }
index 262050fa47bec440048b84b9bcbd57c7bbf00df1..5b7965e9553fef2a74bf002d10576cf3c9438541 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait double {
     fn double(self: Box<Self>) -> usize;
@@ -11,6 +10,6 @@ fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     assert_eq!(x.double(), 6);
 }
index 70ef7ce87ede8eb3663fc6627029ff70d2e46264..3bdc248ff0f7f1dea34472e624358c7931a95db7 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 trait Foo {
     fn foo(&self) -> String;
@@ -18,6 +17,6 @@ fn foo(&self) -> String {
 }
 
 pub fn main() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     assert_eq!(x.foo(), "box 3".to_string());
 }
index 5a5f75eea36792da25e2fa28135f729fdaf5941f..c5f38d815593a50f5463a7f6e154ffb0171d4172 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn test_generic<T: Clone, F>(expected: Box<T>, eq: F) where F: FnOnce(Box<T>, Box<T>) -> bool {
     let actual: Box<T> = match true {
@@ -13,7 +12,7 @@ fn test_box() {
     fn compare_box(b1: Box<bool>, b2: Box<bool>) -> bool {
         return *b1 == *b2;
     }
-    test_generic::<bool, _>(box true, compare_box);
+    test_generic::<bool, _>(Box::new(true), compare_box);
 }
 
 pub fn main() { test_box(); }
index 1d236135cdbd7d3cf979bba302325d2976ae774b..8977ca68efa67aaff4c3a358da986e0f07016aae 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn test_generic<T: Clone, F>(expected: T, eq: F) where F: FnOnce(T, T) -> bool {
     let actual: T = match true {
@@ -11,7 +10,7 @@ fn test_generic<T: Clone, F>(expected: T, eq: F) where F: FnOnce(T, T) -> bool {
 
 fn test_vec() {
     fn compare_box(v1: Box<isize>, v2: Box<isize>) -> bool { return v1 == v2; }
-    test_generic::<Box<isize>, _>(box 1, compare_box);
+    test_generic::<Box<isize>, _>(Box::new(1), compare_box);
 }
 
 pub fn main() { test_vec(); }
index a999541207d14f995ee86fe5de84e20f684b985f..eec9e1f8b4ae1c574fe30a39c5a8c3662af92484 100644 (file)
@@ -1,9 +1,8 @@
 // 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!() };
+    let res: Box<_> = match true { true => { Box::new(100) }, _ => panic!() };
     assert_eq!(*res, 100);
 }
 
index 98dd51811de5b03d5444a0fdfe3b4a479cf1d06d..eb94ee48f9249ccafd531762b3a91b4bb3018044 100644 (file)
@@ -3,8 +3,6 @@
 // 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<usize>,
     y: Box<usize>,
@@ -16,9 +14,9 @@ fn foo(Foo {x, ..}: Foo) -> *const usize {
 }
 
 pub fn main() {
-    let obj: Box<_> = box 1;
+    let obj: Box<_> = Box::new(1);
     let objptr: *const usize = &*obj;
-    let f = Foo {x: obj, y: box 2};
+    let f = Foo { x: obj, y: Box::new(2) };
     let xptr = foo(f);
     assert_eq!(objptr, xptr);
 }
index f46eeb7a020d8f9ef0464d821d3db2a2fd285de8..2d75c12140bf3befa326985ea4536a8fe2206a35 100644 (file)
@@ -5,7 +5,6 @@
 // pattern.
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 fn getaddr(box ref x: Box<usize>) -> *const usize {
     let addr: *const usize = &*x;
@@ -17,11 +16,11 @@ fn checkval(box ref x: Box<usize>) -> usize {
 }
 
 pub fn main() {
-    let obj: Box<_> = box 1;
+    let obj: Box<_> = Box::new(1);
     let objptr: *const usize = &*obj;
     let xptr = getaddr(obj);
     assert_eq!(objptr, xptr);
 
-    let obj = box 22;
+    let obj = Box::new(22);
     assert_eq!(checkval(obj), 22);
 }
index 5bb375d285d38ed258e259763622239f606b464d..b85f4a96a6d50d8c774fea6d8655eb51cfc20df4 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f() {
-    let a: Box<_> = box 1;
+    let a: Box<_> = Box::new(1);
     let b: &isize = &*a;
     println!("{}", b);
 }
index a7e8109b46ca7d573dbbf920bc7ea27ce1051ae9..74ffe2ecdb3a5eea1ac94afaac0a0e4a13eaa1d4 100644 (file)
@@ -1,16 +1,15 @@
 // run-pass
 #![allow(non_shorthand_field_patterns)]
-#![feature(box_syntax)]
 
 struct Pair { a: Box<isize>, b: Box<isize> }
 
 pub fn main() {
-    let mut x: Box<_> = box Pair {a: box 10, b: box 20};
+    let mut x: Box<_> = Box::new(Pair { a: Box::new(10), b: Box::new(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;
+        *a = Box::new(30);
         assert_eq!(**a, 30);
       }
     }
index f5361b118bed85aebab71ece419754014e8c57bd..507478983f68163ab662754b1a4fda0d12fa410d 100644 (file)
@@ -1,9 +1,8 @@
 // run-pass
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 pub fn main() {
-    match box 100 {
+    match Box::new(100) {
       box x => {
         println!("{}", x);
         assert_eq!(x, 100);
index 4b209b20a18aa4e32fcc98d996eae335007c3482..0d750da79e71c042fbb6451d1b399c8d1e9e714d 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 fn foo(x: Option<Box<isize>>, b: bool) -> isize {
     match x {
       None => { 1 }
@@ -12,8 +10,8 @@ fn foo(x: Option<Box<isize>>, b: bool) -> isize {
 }
 
 pub fn main() {
-    foo(Some(box 22), true);
-    foo(Some(box 22), false);
+    foo(Some(Box::new(22)), true);
+    foo(Some(Box::new(22)), false);
     foo(None, true);
     foo(None, false);
 }
index 3e24a1b29c920e66e9ed577bb34b957a524f897c..c628fa49ede4370f64b16257473557180225ada8 100644 (file)
@@ -1,13 +1,13 @@
-#![feature(box_syntax)]
+struct Foo(Box<isize>, isize);
+
+struct Bar(isize, isize);
 
 
 
-struct Foo(Box<isize>, isize);
 
-struct Bar(isize, isize);
 
 fn main() {
-    let x: (Box<_>, _) = (box 1, 2);
+    let x: (Box<_>, _) = (Box::new(1), 2);
     let r = &x.0;
     let y = x; //~ ERROR cannot move out of `x` because it is borrowed
 
@@ -23,7 +23,7 @@ fn main() {
     let b = &mut x.0; //~ ERROR cannot borrow `x.0` as mutable more than once at a time
     a.use_ref();
 
-    let x = Foo(box 1, 2);
+    let x = Foo(Box::new(1), 2);
     let r = &x.0;
     let y = x; //~ ERROR cannot move out of `x` because it is borrowed
     r.use_ref();
index 3abc56153b78a96726fed2b239f0f3b6881ac8ab..b0bb9a0351b4900722ef88a6b881ca66d3090431 100644 (file)
@@ -1,10 +1,10 @@
 // Test that we detect nested calls that could free pointers evaluated
 // for earlier arguments.
 
-#![feature(box_syntax)]
+
 
 fn rewrite(v: &mut Box<usize>) -> usize {
-    *v = box 22;
+    *v = Box::new(22);
     **v
 }
 
@@ -13,7 +13,7 @@ fn add(v: &usize, w: usize) -> usize {
 }
 
 fn implicit() {
-    let mut a: Box<_> = box 1;
+    let mut a: Box<_> = Box::new(1);
 
     // Note the danger here:
     //
@@ -26,7 +26,7 @@ fn implicit() {
 }
 
 fn explicit() {
-    let mut a: Box<_> = box 1;
+    let mut a: Box<_> = Box::new(1);
     add(
         &*a,
         rewrite(&mut a)); //~ ERROR cannot borrow
index fd8df78a5d5a1e4a90b255ba5d5522ec1f11b64b..b2afb6391c1ad53655859f0a710142c0c7289ba0 100644 (file)
@@ -1,10 +1,10 @@
 // Test that we detect nested calls that could free pointers evaluated
 // for earlier arguments.
 
-#![feature(box_syntax)]
+
 
 fn rewrite(v: &mut Box<usize>) -> usize {
-    *v = box 22;
+    *v = Box::new(22);
     **v
 }
 
@@ -13,7 +13,7 @@ fn add(v: &usize, w: Box<usize>) -> usize {
 }
 
 fn implicit() {
-    let mut a: Box<_> = box 1;
+    let mut a: Box<_> = Box::new(1);
 
     // Note the danger here:
     //
@@ -26,7 +26,7 @@ fn implicit() {
 }
 
 fn explicit() {
-    let mut a: Box<_> = box 1;
+    let mut a: Box<_> = Box::new(1);
     add(
         &*a,
         a); //~ ERROR cannot move
index 15c6e8bf210fcec2684fd2e39afc0b4d8b136d3f..24efadc3055117f368fa020dc760ca7416d052e0 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn borrow<F>(x: &isize, f: F) where F: FnOnce(&isize) {
     f(x)
@@ -14,5 +13,5 @@ fn test1(x: &Box<isize>) {
 }
 
 pub fn main() {
-    test1(&box 22);
+    test1(&Box::new(22));
 }
index bc820ee9f9141a7d506748653d0be7d6201e5e2d..6b5544a8a396ba5d9aca5ef46313d04e3b0e5c12 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 struct A;
 
 impl A {
@@ -7,8 +5,10 @@ fn foo(&mut self) {
     }
 }
 
+
+
 pub fn main() {
-    let a: Box<_> = box A;
+    let a: Box<_> = Box::new(A);
     a.foo();
     //~^ ERROR cannot borrow `*a` as mutable, as `a` is not declared as mutable [E0596]
 }
index 7d7e305a31f31ccf3d113e53af7c9ffd3756efa8..76dc01202f6c9266f8b3acd9085fc0e80d7c1410 100644 (file)
@@ -1,7 +1,7 @@
 error[E0596]: cannot borrow `*a` as mutable, as `a` is not declared as mutable
   --> $DIR/borrowck-borrow-immut-deref-of-box-as-mut.rs:12:5
    |
-LL |     let a: Box<_> = box A;
+LL |     let a: Box<_> = Box::new(A);
    |         - help: consider changing this to be mutable: `mut a`
 LL |     a.foo();
    |     ^ cannot borrow as mutable
index a78c66f47cd14c9c3ca73a163a374f013691d11d..1d05845fc6b20d626b5dee1dc515d103cfeffeea 100644 (file)
@@ -1,8 +1,8 @@
-//buggy.rs
+use std::collections::HashMap;
+
+
 
-#![feature(box_syntax)]
 
-use std::collections::HashMap;
 
 fn main() {
     let tmp: Box<_>;
@@ -10,6 +10,6 @@ fn main() {
     buggy_map.insert(42, &*Box::new(1)); //~ ERROR temporary value dropped while borrowed
 
     // but it is ok if we use a temporary
-    tmp = box 2;
+    tmp = Box::new(2);
     buggy_map.insert(43, &*tmp);
 }
index e5591f500380b5c9b1cdbef060f3e09d08e5c7ce..e880f876f91a94a74444433184a987b176ed7ce9 100644 (file)
@@ -3,8 +3,6 @@
 
 // run-pass
 
-#![feature(box_syntax)]
-
 struct A {
     x: Box<isize>,
     y: isize,
@@ -26,97 +24,97 @@ struct D {
 }
 
 fn copy_after_move() {
-    let a: Box<_> = box A { x: box 0, y: 1 };
+    let a: Box<_> = Box::new(A { x: Box::new(0), y: 1 });
     let _x = a.x;
     let _y = a.y;
 }
 
 fn move_after_move() {
-    let a: Box<_> = box B { x: box 0, y: box 1 };
+    let a: Box<_> = Box::new(B { x: Box::new(0), y: Box::new(1) });
     let _x = a.x;
     let _y = a.y;
 }
 
 fn borrow_after_move() {
-    let a: Box<_> = box A { x: box 0, y: 1 };
+    let a: Box<_> = Box::new(A { x: Box::new(0), y: 1 });
     let _x = a.x;
     let _y = &a.y;
 }
 
 fn move_after_borrow() {
-    let a: Box<_> = box B { x: box 0, y: box 1 };
+    let a: Box<_> = Box::new(B { x: Box::new(0), y: Box::new(1) });
     let _x = &a.x;
     let _y = a.y;
     use_imm(_x);
 }
 fn copy_after_mut_borrow() {
-    let mut a: Box<_> = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = Box::new(A { x: Box::new(0), y: 1 });
     let _x = &mut a.x;
     let _y = a.y;
     use_mut(_x);
 }
 fn move_after_mut_borrow() {
-    let mut a: Box<_> = box B { x: box 0, y: box 1 };
+    let mut a: Box<_> = Box::new(B { x: Box::new(0), y: Box::new(1) });
     let _x = &mut a.x;
     let _y = a.y;
     use_mut(_x);
 }
 fn borrow_after_mut_borrow() {
-    let mut a: Box<_> = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = Box::new(A { x: Box::new(0), y: 1 });
     let _x = &mut a.x;
     let _y = &a.y;
     use_mut(_x);
 }
 fn mut_borrow_after_borrow() {
-    let mut a: Box<_> = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = Box::new(A { x: Box::new(0), y: 1 });
     let _x = &a.x;
     let _y = &mut a.y;
     use_imm(_x);
 }
 fn copy_after_move_nested() {
-    let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let a: Box<_> = Box::new(C { x: Box::new(A { x: Box::new(0), y: 1 }), y: 2 });
     let _x = a.x.x;
     let _y = a.y;
 }
 
 fn move_after_move_nested() {
-    let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let a: Box<_> = Box::new(D { x: Box::new(A { x: Box::new(0), y: 1 }), y: Box::new(2) });
     let _x = a.x.x;
     let _y = a.y;
 }
 
 fn borrow_after_move_nested() {
-    let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let a: Box<_> = Box::new(C { x: Box::new(A { x: Box::new(0), y: 1 }), y: 2 });
     let _x = a.x.x;
     let _y = &a.y;
 }
 
 fn move_after_borrow_nested() {
-    let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let a: Box<_> = Box::new(D { x: Box::new(A { x: Box::new(0), y: 1 }), y: Box::new(2) });
     let _x = &a.x.x;
     let _y = a.y;
     use_imm(_x);
 }
 fn copy_after_mut_borrow_nested() {
-    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = Box::new(C { x: Box::new(A { x: Box::new(0), y: 1 }), y: 2 });
     let _x = &mut a.x.x;
     let _y = a.y;
     use_mut(_x);
 }
 fn move_after_mut_borrow_nested() {
-    let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let mut a: Box<_> = Box::new(D { x: Box::new(A { x: Box::new(0), y: 1 }), y: Box::new(2) });
     let _x = &mut a.x.x;
     let _y = a.y;
     use_mut(_x);
 }
 fn borrow_after_mut_borrow_nested() {
-    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = Box::new(C { x: Box::new(A { x: Box::new(0), y: 1 }), y: 2 });
     let _x = &mut a.x.x;
     let _y = &a.y;
     use_mut(_x);
 }
 fn mut_borrow_after_borrow_nested() {
-    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = Box::new(C { x: Box::new(A { x: Box::new(0), y: 1 }), y: 2 });
     let _x = &a.x.x;
     let _y = &mut a.y;
     use_imm(_x);
index 2dc405ffcd4c0a100c0a3ee24a80e9af9456a214..a8225f2faf16613bd034167a8577ae94e97c55ee 100644 (file)
@@ -1,8 +1,6 @@
 // Tests that two closures cannot simultaneously have mutable
 // and immutable access to the variable. Issue #6801.
 
-#![feature(box_syntax)]
-
 fn get(x: &isize) -> isize {
     *x
 }
@@ -11,6 +9,8 @@ fn set(x: &mut isize) {
     *x = 4;
 }
 
+
+
 fn a() {
     let mut x = 3;
     let c1 = || x = 4;
@@ -52,7 +52,7 @@ fn e() {
 }
 
 fn f() {
-    let mut x: Box<_> = box 3;
+    let mut x: Box<_> = Box::new(3);
     let c1 = || get(&*x);
     *x = 5;
     //~^ ERROR cannot assign to `*x` because it is borrowed
@@ -64,7 +64,7 @@ struct Foo {
         f: Box<isize>
     }
 
-    let mut x: Box<_> = box Foo { f: box 3 };
+    let mut x: Box<_> = Box::new(Foo { f: Box::new(3) });
     let c1 = || get(&*x.f);
     *x.f = 5;
     //~^ ERROR cannot assign to `*x.f` because it is borrowed
@@ -76,7 +76,7 @@ struct Foo {
         f: Box<isize>
     }
 
-    let mut x: Box<_> = box Foo { f: box 3 };
+    let mut x: Box<_> = Box::new(Foo { f: Box::new(3) });
     let c1 = || get(&*x.f);
     let c2 = || *x.f = 5;
     //~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
index 2a1757231db851c814c7e526e861652d23a051f2..63a75cdff42de16773afffefc5495ffc6a50d609 100644 (file)
@@ -2,7 +2,7 @@
 // access to the variable, whether that mutable access be used
 // for direct assignment or for taking mutable ref. Issue #6801.
 
-#![feature(box_syntax)]
+
 
 
 
@@ -48,7 +48,7 @@ struct Foo {
         f: Box<isize>
     }
 
-    let mut x: Box<_> = box Foo { f: box 3 };
+    let mut x: Box<_> = Box::new(Foo { f: Box::new(3) });
     let c1 = to_fn_mut(|| set(&mut *x.f));
     let c2 = to_fn_mut(|| set(&mut *x.f));
     //~^ ERROR cannot borrow `x` as mutable more than once
index 5fe51654f3b7977ecf7c8f2024ed676403892d17..cdff8f9e890c61680df148c817f7d9e0743acd30 100644 (file)
@@ -2,7 +2,7 @@
 // access to the variable, whether that mutable access be used
 // for direct assignment or for taking mutable ref. Issue #6801.
 
-#![feature(box_syntax)]
+
 
 fn to_fn_mut<F: FnMut()>(f: F) -> F { f }
 
@@ -44,7 +44,7 @@ struct Foo {
         f: Box<isize>
     }
 
-    let mut x: Box<_> = box Foo { f: box 3 };
+    let mut x: Box<_> = Box::new(Foo { f: Box::new(3) });
     let c1 = to_fn_mut(|| set(&mut *x.f));
     let c2 = to_fn_mut(|| set(&mut *x.f));
     //~^ ERROR cannot borrow `x` as mutable more than once
index e9f65c4ff7df419d14430223b669ee319824b719..be5f1f873df52bfaa6926036a26e9f67e6e8418f 100644 (file)
@@ -2,8 +2,6 @@
 // cannot also be supplied a borrowed version of that
 // variable's contents. Issue #11192.
 
-#![feature(box_syntax)]
-
 struct Foo {
   x: isize
 }
@@ -14,10 +12,12 @@ fn drop(&mut self) {
   }
 }
 
+
+
 fn main() {
-  let mut ptr: Box<_> = box Foo { x: 0 };
+  let mut ptr: Box<_> = Box::new(Foo { x: 0 });
   let mut test = |foo: &Foo| {
-    ptr = box Foo { x: ptr.x + 1 };
+    ptr = Box::new(Foo { x: ptr.x + 1 });
   };
   test(&*ptr); //~ ERROR cannot borrow `*ptr`
 }
index a6dbcf36077a728b704effd7ccff75c735edcb37..30900a3b6d96eadc5989ea4ae6d5e737cf7f3461 100644 (file)
@@ -3,7 +3,7 @@ error[E0502]: cannot borrow `*ptr` as immutable because it is also borrowed as m
    |
 LL |   let mut test = |foo: &Foo| {
    |                  ----------- mutable borrow occurs here
-LL |     ptr = box Foo { x: ptr.x + 1 };
+LL |     ptr = Box::new(Foo { x: ptr.x + 1 });
    |     --- first borrow occurs due to use of `ptr` in closure
 LL |   };
 LL |   test(&*ptr);
index cb1ba90de891e529f0e34740bd5485dc1ff0aedf..dd6708582c1b4b709015ab89d1a2a5db1b89e83f 100644 (file)
@@ -3,89 +3,87 @@
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 struct A { a: isize, b: Box<isize> }
 struct B { a: Box<isize>, b: Box<isize> }
 
 fn move_after_copy() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.a);
     drop(x.b);
 }
 
 fn move_after_fu_copy() {
-    let x = A { a: 1, b: box 2 };
-    let _y = A { b: box 3, .. x };
+    let x = A { a: 1, b: Box::new(2) };
+    let _y = A { b: Box::new(3), .. x };
     drop(x.b);
 }
 
 fn fu_move_after_copy() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.a);
     let _y = A { a: 3, .. x };
 }
 
 fn fu_move_after_fu_copy() {
-    let x = A { a: 1, b: box 2 };
-    let _y = A { b: box 3, .. x };
+    let x = A { a: 1, b: Box::new(2) };
+    let _y = A { b: Box::new(3), .. x };
     let _z = A { a: 4, .. x };
 }
 
 fn copy_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     drop(x.a);
 }
 
 fn copy_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let y = A { a: 3, .. x };
     drop(x.a);
 }
 
 fn fu_copy_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    let _y = A { b: box 3, .. x };
+    let _y = A { b: Box::new(3), .. x };
 }
 
 fn fu_copy_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    let _z = A { b: box 3, .. x };
+    let _z = A { b: Box::new(3), .. x };
 }
 
 fn borrow_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     let p = &x.a;
     drop(*p);
 }
 
 fn borrow_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
     let p = &x.a;
     drop(*p);
 }
 
 fn move_after_borrow() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let p = &x.a;
     drop(x.b);
     drop(*p);
 }
 
 fn fu_move_after_borrow() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let p = &x.a;
     let _y = A { a: 3, .. x };
     drop(*p);
 }
 
 fn mut_borrow_after_mut_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.a;
     let q = &mut x.b;
     drop(*p);
@@ -93,134 +91,134 @@ fn mut_borrow_after_mut_borrow() {
 }
 
 fn move_after_move() {
-    let x = B { a: box 1, b: box 2 };
+    let x = B { a: Box::new(1), b: Box::new(2) };
     drop(x.a);
     drop(x.b);
 }
 
 fn move_after_fu_move() {
-    let x = B { a: box 1, b: box 2 };
-    let y = B { a: box 3, .. x };
+    let x = B { a: Box::new(1), b: Box::new(2) };
+    let y = B { a: Box::new(3), .. x };
     drop(x.a);
 }
 
 fn fu_move_after_move() {
-    let x = B { a: box 1, b: box 2 };
+    let x = B { a: Box::new(1), b: Box::new(2) };
     drop(x.a);
-    let z = B { a: box 3, .. x };
+    let z = B { a: Box::new(3), .. x };
     drop(z.b);
 }
 
 fn fu_move_after_fu_move() {
-    let x = B { a: box 1, b: box 2 };
-    let _y = B { b: box 3, .. x };
-    let _z = B { a: box 4, .. x };
+    let x = B { a: Box::new(1), b: Box::new(2) };
+    let _y = B { b: Box::new(3), .. x };
+    let _z = B { a: Box::new(4), .. x };
 }
 
 fn copy_after_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     drop(*x.b);
 }
 
 fn copy_after_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     drop(*x.b);
 }
 
 fn copy_after_field_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    x.b = box 3;
+    x.b = Box::new(3);
     drop(*x.b);
 }
 
 fn copy_after_field_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x.b = box 3;
+    x.b = Box::new(3);
     drop(*x.b);
 }
 
 fn borrow_after_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     let p = &x.b;
     drop(**p);
 }
 
 fn borrow_after_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     let p = &x.b;
     drop(**p);
 }
 
 fn borrow_after_field_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    x.b = box 3;
+    x.b = Box::new(3);
     let p = &x.b;
     drop(**p);
 }
 
 fn borrow_after_field_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x.b = box 3;
+    x.b = Box::new(3);
     let p = &x.b;
     drop(**p);
 }
 
 fn move_after_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = x.b;
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     drop(x.b);
 }
 
 fn move_after_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x = A { a: 3, b: box 4 };
+    x = A { a: 3, b: Box::new(4) };
     drop(x.b);
 }
 
 fn move_after_field_assign_after_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     drop(x.b);
-    x.b = box 3;
+    x.b = Box::new(3);
     drop(x.b);
 }
 
 fn move_after_field_assign_after_fu_move() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
-    x.b = box 3;
+    x.b = Box::new(3);
     drop(x.b);
 }
 
 fn copy_after_assign_after_uninit() {
     let mut x: A;
-    x = A { a: 1, b: box 2 };
+    x = A { a: 1, b: Box::new(2) };
     drop(x.a);
 }
 
 fn borrow_after_assign_after_uninit() {
     let mut x: A;
-    x = A { a: 1, b: box 2 };
+    x = A { a: 1, b: Box::new(2) };
     let p = &x.a;
     drop(*p);
 }
 
 fn move_after_assign_after_uninit() {
     let mut x: A;
-    x = A { a: 1, b: box 2 };
+    x = A { a: 1, b: Box::new(2) };
     drop(x.b);
 }
 
index ab607c2acbd4b15b595bd222f9db68edf6439cda..50edfb6ba2db16bff9620e6f5fcba6006798d6e1 100644 (file)
@@ -1,49 +1,49 @@
-#![feature(box_syntax)]
-
 struct A { a: isize, b: Box<isize> }
 
+
+
 fn deref_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     drop(*x.b); //~ ERROR use of moved value: `x.b`
 }
 
 fn deref_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let y = A { a: 3, .. x };
     drop(*x.b); //~ ERROR use of moved value: `x.b`
 }
 
 fn borrow_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     let p = &x.b; //~ ERROR borrow of moved value: `x.b`
     drop(**p);
 }
 
 fn borrow_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
     let p = &x.b; //~ ERROR borrow of moved value: `x.b`
     drop(**p);
 }
 
 fn move_after_borrow() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let p = &x.b;
     drop(x.b); //~ ERROR cannot move out of `x.b` because it is borrowed
     drop(**p);
 }
 
 fn fu_move_after_borrow() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let p = &x.b;
     let _y = A { a: 3, .. x }; //~ ERROR cannot move out of `x.b` because it is borrowed
     drop(**p);
 }
 
 fn mut_borrow_after_mut_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.a;
     let q = &mut x.a; //~ ERROR cannot borrow `x.a` as mutable more than once at a time
     drop(*p);
@@ -51,25 +51,25 @@ fn mut_borrow_after_mut_borrow() {
 }
 
 fn move_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     drop(x.b);  //~ ERROR use of moved value: `x.b`
 }
 
 fn move_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
     drop(x.b);  //~ ERROR use of moved value: `x.b`
 }
 
 fn fu_move_after_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     drop(x.b);
     let _z = A { a: 3, .. x };  //~ ERROR use of moved value: `x.b`
 }
 
 fn fu_move_after_fu_move() {
-    let x = A { a: 1, b: box 2 };
+    let x = A { a: 1, b: Box::new(2) };
     let _y = A { a: 3, .. x };
     let _z = A { a: 4, .. x };  //~ ERROR use of moved value: `x.b`
 }
@@ -91,7 +91,7 @@ fn borrow_after_field_assign_after_uninit() {
 
 fn move_after_field_assign_after_uninit() {
     let mut x: A;
-    x.b = box 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
+    x.b = Box::new(1); //~ ERROR assign to part of possibly-uninitialized variable: `x`
     drop(x.b);
 }
 
index f1601336fca9b5e2b49a1d0898e3c9d455243033..bb4d2f06016b9ecc5e3126fe662a79617d9892b3 100644 (file)
@@ -123,7 +123,7 @@ LL |     x.a = 1;
 error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-field-sensitivity.rs:94:5
    |
-LL |     x.b = box 1;
+LL |     x.b = Box::new(1);
    |     ^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 14 previous errors
index de75368578d9fda69f54330165d48f576440626c..389b8a43c0551391d9c8a8c74cee0e5d5b64317c 100644 (file)
@@ -1,6 +1,6 @@
 // Issue #16205.
 
-#![feature(box_syntax)]
+
 
 struct Foo {
     a: [Box<isize>; 3],
@@ -13,12 +13,12 @@ fn main() {
     }
 
     let f = Foo {
-        a: [box 3, box 4, box 5],
+        a: [Box::new(3), Box::new(4), Box::new(5)],
     };
     for &a in &f.a {  //~ ERROR cannot move out
     }
 
-    let x: Option<Box<_>> = Some(box 1);
+    let x: Option<Box<_>> = Some(Box::new(1));
     for &a in x.iter() {    //~ ERROR cannot move out
     }
 }
index e8c9019264fe7343e658960ae9a2156f28aeffc9..003533a51844d4ad87b3d4920e6b28e70eeed294 100644 (file)
@@ -4,14 +4,14 @@
 // Also includes tests of the errors reported when the Box in question
 // is immutable (#14270).
 
-#![feature(box_syntax)]
+
 
 struct A { a: isize }
 struct B<'a> { a: Box<&'a mut isize> }
 
 fn indirect_write_to_imm_box() {
     let mut x: isize = 1;
-    let y: Box<_> = box &mut x;
+    let y: Box<_> = Box::new(&mut x);
     let p = &y;
     ***p = 2; //~ ERROR cannot assign to `***p`
     drop(p);
@@ -19,7 +19,7 @@ fn indirect_write_to_imm_box() {
 
 fn borrow_in_var_from_var() {
     let mut x: isize = 1;
-    let mut y: Box<_> = box &mut x;
+    let mut y: Box<_> = Box::new(&mut x);
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
@@ -29,7 +29,7 @@ fn borrow_in_var_from_var() {
 
 fn borrow_in_var_from_var_via_imm_box() {
     let mut x: isize = 1;
-    let y: Box<_> = box &mut x;
+    let y: Box<_> = Box::new(&mut x);
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
@@ -39,7 +39,7 @@ fn borrow_in_var_from_var_via_imm_box() {
 
 fn borrow_in_var_from_field() {
     let mut x = A { a: 1 };
-    let mut y: Box<_> = box &mut x.a;
+    let mut y: Box<_> = Box::new(&mut x.a);
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
@@ -49,7 +49,7 @@ fn borrow_in_var_from_field() {
 
 fn borrow_in_var_from_field_via_imm_box() {
     let mut x = A { a: 1 };
-    let y: Box<_> = box &mut x.a;
+    let y: Box<_> = Box::new(&mut x.a);
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
@@ -59,7 +59,7 @@ fn borrow_in_var_from_field_via_imm_box() {
 
 fn borrow_in_field_from_var() {
     let mut x: isize = 1;
-    let mut y = B { a: box &mut x };
+    let mut y = B { a: Box::new(&mut x) };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
@@ -69,7 +69,7 @@ fn borrow_in_field_from_var() {
 
 fn borrow_in_field_from_var_via_imm_box() {
     let mut x: isize = 1;
-    let y = B { a: box &mut x };
+    let y = B { a: Box::new(&mut x) };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
@@ -79,7 +79,7 @@ fn borrow_in_field_from_var_via_imm_box() {
 
 fn borrow_in_field_from_field() {
     let mut x = A { a: 1 };
-    let mut y = B { a: box &mut x.a };
+    let mut y = B { a: Box::new(&mut x.a) };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
@@ -89,7 +89,7 @@ fn borrow_in_field_from_field() {
 
 fn borrow_in_field_from_field_via_imm_box() {
     let mut x = A { a: 1 };
-    let y = B { a: box &mut x.a };
+    let y = B { a: Box::new(&mut x.a) };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
index c38293740edaa4c6b385c9c30023c8089149cd32..0fb2267b982ea6fb9505d1b47e2fc1270a932d60 100644 (file)
@@ -1,9 +1,9 @@
-#![feature(box_syntax)]
-
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { }  }
+impl<T> Fake for T { }
 
 
 fn main() {
-    let x: Option<Box<_>> = Some(box 1);
+    let x: Option<Box<_>> = Some(Box::new(1));
     match x {
       Some(ref _y) => {
         let _a = x; //~ ERROR cannot move
@@ -12,6 +12,3 @@ fn main() {
       _ => {}
     }
 }
-
-trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { }  }
-impl<T> Fake for T { }
index cea561104874499b20da10389b83aeb78b4b119d..7dbac02154a6e29bddf4ad389f38a403b7bf25b8 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
-
 fn main() {
-    let x: Option<Box<_>> = Some(box 1);
+
+    let x: Option<Box<_>> = Some(Box::new(1));
+
     match x {
       Some(ref y) => {
         let _b = *y; //~ ERROR cannot move out
index 1150346f752faa006071e119a620a6114c8c1d0f..19a0dd0c6b17b7e3426c48f03ab6762c26a3da9b 100644 (file)
@@ -4,7 +4,7 @@
 // either genuine or would require more advanced changes.  The latter
 // cases are noted.
 
-#![feature(box_syntax)]
+
 
 fn borrow(_v: &isize) {}
 fn borrow_mut(_v: &mut isize) {}
@@ -13,15 +13,15 @@ fn for_func<F>(_f: F) where F: FnOnce() -> bool { panic!() }
 fn produce<T>() -> T { panic!(); }
 
 fn inc(v: &mut Box<isize>) {
-    *v = box (**v + 1);
+    *v = Box::new(**v + 1);
 }
 
 fn pre_freeze_cond() {
     // In this instance, the freeze is conditional and starts before
     // the mut borrow.
 
-    let u = box 0;
-    let mut v: Box<_> = box 3;
+    let u = Box::new(0);
+    let mut v: Box<_> = Box::new(3);
     let mut _w = &u;
     if cond() {
         _w = &v;
@@ -34,8 +34,8 @@ fn pre_freeze_else() {
     // In this instance, the freeze and mut borrow are on separate sides
     // of the if.
 
-    let u = box 0;
-    let mut v: Box<_> = box 3;
+    let u = Box::new(0);
+    let mut v: Box<_> = Box::new(3);
     let mut _w = &u;
     if cond() {
         _w = &v;
index b650df91ca23cfadce567474a31518b79d17c86f..548ffbd515e98836fe2bf8b2c22b92674078a14d 100644 (file)
@@ -1,18 +1,18 @@
-#![feature(box_syntax)]
-
 fn borrow(_v: &isize) {}
 fn borrow_mut(_v: &mut isize) {}
 fn cond() -> bool { panic!() }
 fn produce<T>() -> T { panic!(); }
 
+
 fn inc(v: &mut Box<isize>) {
-    *v = box (**v + 1);
+    *v = Box::new(**v + 1);
 }
 
+
 fn loop_overarching_alias_mut() {
     // In this instance, the borrow ends on the line before the loop
 
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     let mut x = &mut v;
     **x += 1;
     loop {
@@ -23,18 +23,18 @@ fn loop_overarching_alias_mut() {
 fn block_overarching_alias_mut() {
     // In this instance, the borrow encompasses the entire closure call.
 
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     let mut x = &mut v;
     for _ in 0..3 {
         borrow(&*v); //~ ERROR cannot borrow
     }
-    *x = box 5;
+    *x = Box::new(5);
 }
 fn loop_aliased_mut() {
     // In this instance, the borrow ends right after each assignment to _x
 
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut _x = &w;
     loop {
         borrow_mut(&mut *v); // OK
@@ -45,8 +45,8 @@ fn loop_aliased_mut() {
 fn while_aliased_mut() {
     // In this instance, the borrow ends right after each assignment to _x
 
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut _x = &w;
     while cond() {
         borrow_mut(&mut *v); // OK
@@ -58,8 +58,8 @@ fn while_aliased_mut() {
 fn loop_aliased_mut_break() {
     // In this instance, the borrow ends right after each assignment to _x
 
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut _x = &w;
     loop {
         borrow_mut(&mut *v);
@@ -72,8 +72,8 @@ fn loop_aliased_mut_break() {
 fn while_aliased_mut_break() {
     // In this instance, the borrow ends right after each assignment to _x
 
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut _x = &w;
     while cond() {
         borrow_mut(&mut *v);
@@ -84,8 +84,8 @@ fn while_aliased_mut_break() {
 }
 
 fn while_aliased_mut_cond(cond: bool, cond2: bool) {
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut x = &mut w;
     while cond {
         **x += 1;
index f02c357f48b4c919ade516158e3da2318801c600..df7c86b85623e76f5d02c0c0b73575ad459b0057 100644 (file)
@@ -7,7 +7,7 @@ LL |     for _ in 0..3 {
 LL |         borrow(&*v);
    |                ^^^ immutable borrow occurs here
 LL |     }
-LL |     *x = box 5;
+LL |     *x = Box::new(5);
    |     -- mutable borrow later used here
 
 error[E0502]: cannot borrow `*v` as immutable because it is also borrowed as mutable
index 0eb62ede5d65a5ca4f18a3ae4bcfb79a43aa7a98..564c57044a37e015cddeec14d365cfa7b5700f44 100644 (file)
@@ -4,7 +4,7 @@
 // either genuine or would require more advanced changes.  The latter
 // cases are noted.
 
-#![feature(box_syntax)]
+
 
 fn borrow(_v: &isize) {}
 fn borrow_mut(_v: &mut isize) {}
@@ -13,13 +13,13 @@ fn for_func<F>(_f: F) where F: FnOnce() -> bool { panic!() }
 fn produce<T>() -> T { panic!(); }
 
 fn inc(v: &mut Box<isize>) {
-    *v = box (**v + 1);
+    *v = Box::new(**v + 1);
 }
 
 fn pre_freeze() {
     // In this instance, the freeze starts before the mut borrow.
 
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     let _w = &v;
     borrow_mut(&mut *v); //~ ERROR cannot borrow
     _w.use_ref();
@@ -28,7 +28,7 @@ fn pre_freeze() {
 fn post_freeze() {
     // In this instance, the const alias starts after the borrow.
 
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     borrow_mut(&mut *v);
     let _w = &v;
 }
index 9fa46563fdf801ab8788e76452d6d464ec23f982..e536d404099273ede42310aef0bc6c0b3992cbad 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 use std::thread;
 
 
@@ -8,8 +6,10 @@ fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
     f(v);
 }
 
+
+
 fn box_imm() {
-    let v: Box<_> = box 3;
+    let v: Box<_> = Box::new(3);
     let w = &v;
     thread::spawn(move|| {
     //~^ ERROR cannot move out of `v` because it is borrowed
@@ -19,7 +19,7 @@ fn box_imm() {
 }
 
 fn box_imm_explicit() {
-    let v: Box<_> = box 3;
+    let v: Box<_> = Box::new(3);
     let w = &v;
     thread::spawn(move|| {
     //~^ ERROR cannot move
index bde73219f70ede7df3ae5e2a3882c6f0be916de8..f3f443721b5ec69e749ef444233998bb1d36b398 100644 (file)
@@ -1,12 +1,12 @@
-#![feature(box_syntax)]
+fn take(_v: Box<isize>) {
+}
+
 
 
 
-fn take(_v: Box<isize>) {
-}
 
 fn box_imm() {
-    let v = box 3;
+    let v = Box::new(3);
     let w = &v;
     take(v); //~ ERROR cannot move out of `v` because it is borrowed
     w.use_ref();
index da30bfa29bbf7ad336a130d9b1d928c2a67928e0..33d6af303102af3d267926cb3fe4d9b6596eac86 100644 (file)
@@ -1,14 +1,14 @@
-#![feature(box_syntax)]
-
 fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
     f(v);
 }
 
+
+
 fn box_imm() {
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     borrow(&*v,
            |w| { //~ ERROR cannot borrow `v` as mutable
-            v = box 4;
+            v = Box::new(4);
             assert_eq!(*v, 3);
             assert_eq!(*w, 4);
         })
index 1d1522a15b1ed0ae19464da611137f6a3741e918..fa5308c2903906179b4f1be41b1b5abe0fc441f1 100644 (file)
@@ -7,7 +7,7 @@ LL |     borrow(&*v,
    |     immutable borrow later used by call
 LL |            |w| {
    |            ^^^ mutable borrow occurs here
-LL |             v = box 4;
+LL |             v = Box::new(4);
    |             - second borrow occurs due to use of `v` in closure
 
 error: aborting due to previous error
index 1baa94edfbe58b2cb164e53f339002b90d457dc7..b8f1650fcdc599bf5d4524f552c5d57cfbc4d245 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
+
 
 use std::ops::Add;
 
@@ -12,12 +12,12 @@ impl Add for Foo {
     fn add(self, f: Foo) -> Foo {
         let Foo(box i) = self;
         let Foo(box j) = f;
-        Foo(box (i + j))
+        Foo(Box::new(i + j))
     }
 }
 
 fn main() {
-    let x = Foo(box 3);
+    let x = Foo(Box::new(3));
     let _y = {x} + x.clone(); // the `{x}` forces a move to occur
     //~^ ERROR borrow of moved value: `x`
 }
index 095ae7f56b22e5643219552e332d6538596c2a4c..cd288065b74f7df96b14e5c6bb09e037bdb7f3b0 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: borrow of moved value: `x`
   --> $DIR/borrowck-loan-in-overloaded-op.rs:21:20
    |
-LL |     let x = Foo(box 3);
+LL |     let x = Foo(Box::new(3));
    |         - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait
 LL |     let _y = {x} + x.clone(); // the `{x}` forces a move to occur
    |               -    ^ value borrowed here after move
index 628e49f574cf2f5b92f71eaaee010f9b29459ad2..4e969f6ed83d30935dd74dfd89801a0b5ed8f17b 100644 (file)
@@ -6,9 +6,7 @@
 // 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
@@ -23,7 +21,7 @@ fn elaborate_stm(&mut self, s: Box<Bar>) -> Box<Bar> {
     macro_rules! declare {
       ($id:expr, $rest:expr) => ({
         self.check_id($id);
-        box Bar::Bar2($id, $rest)
+        Box::new(Bar::Bar2($id, $rest))
       })
     }
     match s {
index 98e4b881893cbb4e93e1ef339890cf44b76ccf48..e7a48ebf6ca9b0cd001dc50f2e84740e24e43b27 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let bar: Box<_> = box 3;
+    let bar: Box<_> = Box::new(3);
     let h = || -> isize { *bar };
     assert_eq!(h(), 3);
 }
index a825ed5e89acd8087a3c0c9510733f834611e8fe..f26edef17f34963fd7fed5f2638d4ad323dfd407 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax,unboxed_closures)]
+#![feature(unboxed_closures)]
 
 fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
 pub fn main() {
-    let bar: Box<_> = box 3;
+    let bar: Box<_> = Box::new(3);
     let _g = to_fn_mut(|| {
         let _h = to_fn_once(move || -> isize { *bar }); //~ ERROR cannot move out of
     });
index 05489cf18e7fc9a5b2ebc352536a4b1d7a46f8ea..257ec3fbb7fa237266afbbf31f219c92eea359e4 100644 (file)
@@ -1,7 +1,7 @@
 error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-move-by-capture.rs:9:29
    |
-LL |       let bar: Box<_> = box 3;
+LL |       let bar: Box<_> = Box::new(3);
    |           --- captured outer variable
 LL |       let _g = to_fn_mut(|| {
    |  ________________________-
index 7ef59f50c0332c856247b5df47e13d1ca73f1492..ef38cbb63a5e3455cb31328eaa43ba5eb3ee5af2 100644 (file)
@@ -1,14 +1,14 @@
-#![feature(box_syntax)]
-
 enum Foo {
     Foo1(Box<u32>, Box<u32>),
     Foo2(Box<u32>),
     Foo3,
 }
 
+
+
 fn blah() {
-    let f = &Foo::Foo1(box 1, box 2);
-    match *f {             //~ ERROR cannot move out of
+    let f = &Foo::Foo1(Box::new(1), Box::new(2));
+    match *f { //~ ERROR cannot move out of
         Foo::Foo1(num1,
                   num2) => (),
         Foo::Foo2(num) => (),
@@ -42,8 +42,8 @@ struct A {
 fn free<T>(_: T) {}
 
 fn blah2() {
-    let a = &A { a: box 1 };
-    match a.a {           //~ ERROR cannot move out of
+    let a = &A { a: Box::new(1) };
+    match a.a { //~ ERROR cannot move out of
         n => {
             free(n)
         }
index e058c80651679f3e22f245c54d0fa370f4af5954..71405f7a7329d1c080b24e64e27bcaa4ddc4dd2d 100644 (file)
@@ -3,10 +3,10 @@
 
 
 
-#![feature(box_syntax)]
+
 
 fn main() {
-    let a: Box<Box<_>> = box box 2;
+    let a: Box<Box<_>> = Box::new(Box::new(2));
     let b = &a;
 
     let z = *a; //~ ERROR: cannot move out of `*a` because it is borrowed
index 233d0a733e316c9564fdfff57383fa65364df1ad..72e7b5a716273a4afaab55700ac192c357955d52 100644 (file)
@@ -1,11 +1,11 @@
-#![feature(box_syntax)]
-
 fn call_f<F:FnOnce() -> isize>(f: F) -> isize {
     f()
 }
 
+
+
 fn main() {
-    let t: Box<_> = box 3;
+    let t: Box<_> = Box::new(3);
 
     call_f(move|| { *t + 1 });
     call_f(move|| { *t + 1 }); //~ ERROR use of moved value
index 1ac4999e6e11d8d78144fbfa8f79eb2ddca652b9..edd597fe30bd291371523b69e5c8e9a0e534fe1e 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: use of moved value: `t`
   --> $DIR/borrowck-move-moved-value-into-closure.rs:11:12
    |
-LL |     let t: Box<_> = box 3;
+LL |     let t: Box<_> = Box::new(3);
    |         - move occurs because `t` has type `Box<isize>`, which does not implement the `Copy` trait
 LL | 
 LL |     call_f(move|| { *t + 1 });
index 4185632c4e2919e05f60d18e0115d3fad3319a6d..38abd19322215207241335a1a8431f8277d89606 100644 (file)
@@ -1,7 +1,7 @@
 // Tests that the borrow checker checks all components of a path when moving
 // out.
 
-#![feature(box_syntax)]
+
 
 struct S {
   x : Box<isize>
@@ -10,7 +10,7 @@ struct S {
 fn f<T>(_: T) {}
 
 fn main() {
-  let a : S = S { x : box 1 };
+  let a : S = S { x : Box::new(1) };
   let pb = &a;
   let S { x: ax } = a;  //~ ERROR cannot move out
   f(pb);
index 9f09f8442c04469397af294522f9539d683cddce..57b3819ac5113641589134e7e750477e2a14a615 100644 (file)
@@ -1,13 +1,13 @@
-#![feature(box_syntax)]
-
 use std::thread;
 
+
 fn borrow<T>(_: &T) { }
 
+
 fn different_vars_after_borrows() {
-    let x1: Box<_> = box 1;
+    let x1: Box<_> = Box::new(1);
     let p1 = &x1;
-    let x2: Box<_> = box 2;
+    let x2: Box<_> = Box::new(2);
     let p2 = &x2;
     thread::spawn(move|| {
         //~^ ERROR cannot move out of `x1` because it is borrowed
@@ -20,9 +20,9 @@ fn different_vars_after_borrows() {
 }
 
 fn different_vars_after_moves() {
-    let x1: Box<_> = box 1;
+    let x1: Box<_> = Box::new(1);
     drop(x1);
-    let x2: Box<_> = box 2;
+    let x2: Box<_> = Box::new(2);
     drop(x2);
     thread::spawn(move|| {
         //~^ ERROR use of moved value: `x1`
@@ -33,7 +33,7 @@ fn different_vars_after_moves() {
 }
 
 fn same_var_after_borrow() {
-    let x: Box<_> = box 1;
+    let x: Box<_> = Box::new(1);
     let p = &x;
     thread::spawn(move|| {
         //~^ ERROR cannot move out of `x` because it is borrowed
@@ -44,7 +44,7 @@ fn same_var_after_borrow() {
 }
 
 fn same_var_after_move() {
-    let x: Box<_> = box 1;
+    let x: Box<_> = Box::new(1);
     drop(x);
     thread::spawn(move|| {
         //~^ ERROR use of moved value: `x`
index e159878619a0bd35b4a9cf4a22226611bc7dbe7e..86d2955e2364f4a3a832c0defb288bcf90bc677b 100644 (file)
@@ -30,7 +30,7 @@ LL |     borrow(&*p2);
 error[E0382]: use of moved value: `x1`
   --> $DIR/borrowck-multiple-captures.rs:27:19
    |
-LL |     let x1: Box<_> = box 1;
+LL |     let x1: Box<_> = Box::new(1);
    |         -- move occurs because `x1` has type `Box<i32>`, which does not implement the `Copy` trait
 LL |     drop(x1);
    |          -- value moved here
@@ -44,7 +44,7 @@ LL |         drop(x1);
 error[E0382]: use of moved value: `x2`
   --> $DIR/borrowck-multiple-captures.rs:27:19
    |
-LL |     let x2: Box<_> = box 2;
+LL |     let x2: Box<_> = Box::new(2);
    |         -- move occurs because `x2` has type `Box<i32>`, which does not implement the `Copy` trait
 LL |     drop(x2);
    |          -- value moved here
@@ -91,7 +91,7 @@ LL |         drop(x);
 error[E0382]: use of moved value: `x`
   --> $DIR/borrowck-multiple-captures.rs:49:19
    |
-LL |     let x: Box<_> = box 1;
+LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 LL |     drop(x);
    |          - value moved here
index 80b3484e0fb23477d127326d44a298c918041a7d..255b4995b640db8368ef046cf3700b1ee5c1f19f 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 use std::mem::swap;
 
@@ -20,7 +19,7 @@ fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&isize) -> bool {
 }
 
 pub fn main() {
-    let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()};
+    let mut ints: Box<_> = Box::new(Ints {sum: Box::new(0), values: Vec::new()});
     add_int(&mut *ints, 22);
     add_int(&mut *ints, 44);
 
index 4c1ff98ce6ec26e6bb71706818d257281ff894b9..f035049d82d8db4fb2bbfb664aaf9b47d689b38d 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 struct Node_ {
     a: Box<Cycle>
 }
@@ -8,8 +6,10 @@ enum Cycle {
     Node(Node_),
     Empty,
 }
+
 fn main() {
-    let mut x: Box<_> = box Cycle::Node(Node_ {a: box Cycle::Empty});
+    let mut x: Box<_> = Box::new(Cycle::Node(Node_ {a: Box::new(Cycle::Empty)}));
+
     // Create a cycle!
     match *x {
       Cycle::Node(ref mut y) => {
index ddf6354c97341550025050317f3855ac04804de6..344d75cc58f02f9801b3364d3458759cc4aff436 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 use std::ops::Index;
 
 struct MyVec<T> {
@@ -14,8 +12,10 @@ fn index(&self, i: usize) -> &T {
     }
 }
 
+
+
 fn main() {
-    let v = MyVec::<Box<_>> { data: vec![box 1, box 2, box 3] };
+    let v = MyVec::<Box<_>> { data: vec![Box::new(1), Box::new(2), Box::new(3)] };
     let good = &v[0]; // Shouldn't fail here
     let bad = v[0];
     //~^ ERROR cannot move out of index of `MyVec<Box<i32>>`
index f62880788edb748f6a50ae2c458c4062c6eb061d..25d3e0b548646bd49815f5d05335457da4bad299 100644 (file)
@@ -1,17 +1,17 @@
-#![feature(box_syntax)]
+fn borrow(_v: &isize) {}
+
 
 
 
-fn borrow(_v: &isize) {}
 
 fn local() {
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     borrow(&*v);
 }
 
 fn local_rec() {
     struct F { f: Box<isize> }
-    let mut v = F {f: box 3};
+    let mut v = F {f: Box::new(3)};
     borrow(&*v.f);
 }
 
@@ -19,35 +19,35 @@ fn local_recs() {
     struct F { f: G }
     struct G { g: H }
     struct H { h: Box<isize> }
-    let mut v = F {f: G {g: H {h: box 3}}};
+    let mut v = F {f: G {g: H {h: Box::new(3)}}};
     borrow(&*v.f.g.h);
 }
 
 fn aliased_imm() {
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     let w = &v;
     borrow(&*v);
     w.use_ref();
 }
 
 fn aliased_mut() {
-    let mut v: Box<_> = box 3;
+    let mut v: Box<_> = Box::new(3);
     let w = &mut v;
     borrow(&*v); //~ ERROR cannot borrow `*v`
     w.use_mut();
 }
 
 fn aliased_other() {
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let x = &mut w;
     borrow(&*v);
     x.use_mut();
 }
 
 fn aliased_other_reassign() {
-    let mut v: Box<_> = box 3;
-    let mut w: Box<_> = box 4;
+    let mut v: Box<_> = Box::new(3);
+    let mut w: Box<_> = Box::new(4);
     let mut x = &mut w;
     x = &mut v;
     borrow(&*v); //~ ERROR cannot borrow `*v`
index bcd1d3ccd8acb754bfd4c50415a3be8a29e87a5e..1cf763f66fd2022f0de9355dbb350cd85b384af9 100644 (file)
@@ -1,41 +1,39 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 struct A { a: isize, b: Box<isize> }
 
 fn field_copy_after_field_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.b;
     drop(x.a);
     **p = 3;
 }
 
 fn fu_field_copy_after_field_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.b;
-    let y = A { b: box 3, .. x };
+    let y = A { b: Box::new(3), .. x };
     drop(y);
     **p = 4;
 }
 
 fn field_deref_after_field_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.a;
     drop(*x.b);
     *p = 3;
 }
 
 fn field_move_after_field_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.a;
     drop(x.b);
     *p = 3;
 }
 
 fn fu_field_move_after_field_borrow() {
-    let mut x = A { a: 1, b: box 2 };
+    let mut x = A { a: 1, b: Box::new(2) };
     let p = &mut x.a;
     let y = A { a: 3, .. x };
     drop(y);
index 95b165d6ef22fe5cb0482db7f966252ecfe0a351..94f88395ff9e2b92c8205a164c5ef23fc136f85f 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
 #[derive(Copy, Clone)]
 struct A { a: isize, b: isize }
 
 struct B { a: isize, b: Box<isize> }
 
+
+
 fn var_copy_after_var_borrow() {
     let mut x: isize = 1;
     let p = &mut x;
@@ -50,21 +50,21 @@ fn fu_field_copy_after_field_borrow() {
 }
 
 fn var_deref_after_var_borrow() {
-    let mut x: Box<isize> = box 1;
+    let mut x: Box<isize> = Box::new(1);
     let p = &mut x;
     drop(*x); //~ ERROR cannot use `*x` because it was mutably borrowed
     **p = 2;
 }
 
 fn field_deref_after_var_borrow() {
-    let mut x = B { a: 1, b: box 2 };
+    let mut x = B { a: 1, b: Box::new(2) };
     let p = &mut x;
     drop(*x.b); //~ ERROR cannot use `*x.b` because it was mutably borrowed
     p.a = 3;
 }
 
 fn field_deref_after_field_borrow() {
-    let mut x = B { a: 1, b: box 2 };
+    let mut x = B { a: 1, b: Box::new(2) };
     let p = &mut x.b;
     drop(*x.b); //~ ERROR cannot use `*x.b` because it was mutably borrowed
     **p = 3;
index 67b6c12ba803a230a09266750e53ec004f8b2698..8a9296c597828adb834b6cb0bebe93f6cfbb464f 100644 (file)
@@ -1,12 +1,12 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
+
 
 fn a() {
-    let mut vec = [box 1, box 2, box 3];
+    let mut vec = [Box::new(1), Box::new(2), Box::new(3)];
     match vec {
         [box ref _a, _, _] => {
         //~^ NOTE borrow of `vec[_]` occurs here
-            vec[0] = box 4; //~ ERROR cannot assign
+            vec[0] = Box::new(4); //~ ERROR cannot assign
             //~^ NOTE assignment to borrowed `vec[_]` occurs here
             _a.use_ref();
             //~^ NOTE borrow later used here
@@ -15,12 +15,12 @@ fn a() {
 }
 
 fn b() {
-    let mut vec = vec![box 1, box 2, box 3];
+    let mut vec = vec![Box::new(1), Box::new(2), Box::new(3)];
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
         &mut [ref _b @ ..] => {
         //~^ borrow of `vec[_]` occurs here
-            vec[0] = box 4; //~ ERROR cannot assign
+            vec[0] = Box::new(4); //~ ERROR cannot assign
             //~^ NOTE assignment to borrowed `vec[_]` occurs here
             _b.use_ref();
             //~^ NOTE borrow later used here
@@ -29,7 +29,7 @@ fn b() {
 }
 
 fn c() {
-    let mut vec = vec![box 1, box 2, box 3];
+    let mut vec = vec![Box::new(1), Box::new(2), Box::new(3)];
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
         //~^ ERROR cannot move out
@@ -50,7 +50,7 @@ fn c() {
 }
 
 fn d() {
-    let mut vec = vec![box 1, box 2, box 3];
+    let mut vec = vec![Box::new(1), Box::new(2), Box::new(3)];
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
         //~^ ERROR cannot move out
@@ -69,7 +69,7 @@ fn d() {
 }
 
 fn e() {
-    let mut vec = vec![box 1, box 2, box 3];
+    let mut vec = vec![Box::new(1), Box::new(2), Box::new(3)];
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
         //~^ ERROR cannot move out
index 36f8f5c9ad73970c810d74edd4079dfb1c6f084b..41c9b3be28164d2dbbce6736e7b073b42a113882 100644 (file)
@@ -4,7 +4,7 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed
 LL |         [box ref _a, _, _] => {
    |              ------ borrow of `vec[_]` occurs here
 LL |
-LL |             vec[0] = box 4;
+LL |             vec[0] = Box::new(4);
    |             ^^^^^^ assignment to borrowed `vec[_]` occurs here
 LL |
 LL |             _a.use_ref();
@@ -16,7 +16,7 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed
 LL |         &mut [ref _b @ ..] => {
    |               ----------- borrow of `vec[_]` occurs here
 LL |
-LL |             vec[0] = box 4;
+LL |             vec[0] = Box::new(4);
    |             ^^^^^^ assignment to borrowed `vec[_]` occurs here
 LL |
 LL |             _b.use_ref();
index 6a0b4ed17b96294866da32d19b3cc142f78e88fa..85e0a840a1961102b60de1617da6073a0850ea5c 100644 (file)
@@ -5,7 +5,7 @@
 // Issue 4691: Ensure that functional-struct-updates operates
 // correctly and moves rather than copy when appropriate.
 
-#![feature(box_syntax, core)]
+#![feature(core)]
 
 struct ncint { v: isize }
 fn ncint(v: isize) -> ncint { ncint { v: v } }
@@ -17,7 +17,7 @@ fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
 
 struct MoveFoo { copied: isize, moved: Box<isize>, }
 impl MoveFoo {
-    fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
+    fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: Box::new(y) } }
 }
 
 struct DropNoFoo { inner: NoFoo }
@@ -53,8 +53,8 @@ fn test0() {
 
     // 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 }};
+    let b = DropMoveFoo { inner: MoveFoo { moved: Box::new(7), ..f.inner }};
+    let c = DropMoveFoo { inner: MoveFoo { moved: Box::new(8), ..f.inner }};
     assert_eq!(f.inner.copied,    5);
     assert_eq!(*f.inner.moved,    6);
 
@@ -69,7 +69,7 @@ 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 b = MoveFoo {moved: Box::new(13), ..f};
     let c = MoveFoo {copied: 14, ..f};
     assert_eq!(b.copied,    11);
     assert_eq!(*b.moved,    13);
index 7e9ff68548225edf9bcd28f809296e964ba97df1..4f560b065f1b55fb7053c9126dd88b89158f0ae0 100644 (file)
@@ -1,14 +1,12 @@
 // check-pass
 
-#![feature(box_syntax)]
-
 struct Foo { a: isize, b: isize }
 
 fn main() {
-    let mut x: Box<_> = box Foo { a: 1, b: 2 };
+    let mut x: Box<_> = Box::new(Foo { a: 1, b: 2 });
     let (a, b) = (&mut x.a, &mut x.b);
 
-    let mut foo: Box<_> = box Foo { a: 1, b: 2 };
+    let mut foo: Box<_> = Box::new(Foo { a: 1, b: 2 });
     let (c, d) = (&mut foo.a, &foo.b);
 
     // We explicitly use the references created above to illustrate that the
index 569769b8213bff69417fc07200b2a9ff175ac535..dd0320bc53ba7d79d1151e7b34ea1ba3e85d845a 100644 (file)
@@ -17,7 +17,6 @@ async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
     //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
     //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
     LockedMarket(generator.lock().unwrap().buy())
-    //~^ ERROR cannot return value referencing temporary value
 }
 
 struct LockedMarket<T>(T);
index 4bd0667304397e0a7b8eb91280cc183c52bcf03b..d2b927fb664c66b1958dbdfd914b771b95b1d2d1 100644 (file)
@@ -7,7 +7,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_>
    |                                                           expected 0 lifetime arguments
    |
 note: struct defined here, with 0 lifetime parameters
-  --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8
+  --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8
    |
 LL | struct LockedMarket<T>(T);
    |        ^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_>
    |                                                           ^^^^^^^^^^^^ expected 1 generic argument
    |
 note: struct defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8
+  --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8
    |
 LL | struct LockedMarket<T>(T);
    |        ^^^^^^^^^^^^ -
@@ -28,16 +28,6 @@ help: add missing generic argument
 LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_, T> {
    |                                                                          +++
 
-error[E0515]: cannot return value referencing temporary value
-  --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5
-   |
-LL |     LockedMarket(generator.lock().unwrap().buy())
-   |     ^^^^^^^^^^^^^-------------------------^^^^^^^
-   |     |            |
-   |     |            temporary value created here
-   |     returns a value referencing data owned by the current function
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0107, E0515.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
index 781d5c14abe9cbfb32ee976ebb4da40e20ef2410..a0a561ab2d21ed9293205383120f151b1b845cfc 100644 (file)
@@ -1,12 +1,10 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 fn foo(x: &mut Box<u8>) {
-    *x = box 5;
+    *x = Box::new(5);
 }
 
 pub fn main() {
-    foo(&mut box 4);
+    foo(&mut Box::new(4));
 }
index bb4c3fac93806e8303d9301609558cb083dfd653..345d6efd2d90ada0f1893a39d027d9033d32d9fb 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 trait Noisy {
   fn speak(&self);
 }
@@ -48,7 +46,9 @@ fn cat(in_x : usize, in_y : isize, in_name: String) -> Cat {
     }
 }
 
+
+
 fn main() {
-  let nyan: Box<dyn Noisy> = box cat(0, 2, "nyan".to_string()) as Box<dyn Noisy>;
+  let nyan: Box<dyn Noisy> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn Noisy>;
   nyan.eat(); //~ ERROR no method named `eat` found
 }
index 915842f3e85f243ba03ee8d6c5604a8b5f42b785..38c717089c46bf1712a8dbea4ee2ef4b0fae9344 100644 (file)
@@ -7,7 +7,7 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax, os)]
+#![feature(os)]
 
 use std::os;
 
@@ -15,7 +15,7 @@ struct Test { x: isize }
 
 impl Test {
     fn get_x(&self) -> Option<Box<isize>> {
-        Some(box self.x)
+        Some(Box::new(self.x))
     }
 }
 
index c5dd87c0f5a1fb712de242c120c997ab00e82559..b80f95b79f91d2966ca82abebd03046008f9816a 100644 (file)
@@ -7,7 +7,6 @@
 // lifetime rules.
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 use std::ops::Drop;
 
@@ -106,8 +105,8 @@ pub fn main() {
     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!(box ref _x, std::boxed::Box::new(AddFlags(1)));
+    end_of_block!(box _x, std::boxed::Box::new(AddFlags(1)));
     end_of_block!(_, { { check_flags(0); &AddFlags(1) } });
     end_of_block!(_, &((Box { f: AddFlags(1) }).f));
     end_of_block!(_, &(([AddFlags(1)])[0]));
index 62f8b81385aa3b2d1b77449742217d365682abaf..eadbe44a8e9dee767d2dd0c67def8eac1038aed8 100644 (file)
@@ -21,8 +21,6 @@
 
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::thread;
 
 enum Conzabble {
@@ -40,7 +38,7 @@ fn get_bar(x: usize) -> Vec<usize> { vec![x * 2] }
 pub fn fails() {
     let x = 2;
     let mut y: Vec<Box<_>> = Vec::new();
-    y.push(box Conzabble::Bickwick(do_it(&get_bar(x))));
+    y.push(Box::new(Conzabble::Bickwick(do_it(&get_bar(x)))));
 }
 
 pub fn main() {
index 1ef2971926796d6023207765746b753884014ff4..9fc661b14777ea6eb4708a37d7d1b05e6ccacf29 100644 (file)
@@ -3,8 +3,6 @@
 #![allow(unused_must_use)]
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::thread;
 
 struct Pair {
@@ -13,7 +11,7 @@ struct Pair {
 }
 
 pub fn main() {
-    let z: Box<_> = box Pair { a : 10, b : 12};
+    let z: Box<_> = Box::new(Pair { a : 10, b : 12});
 
     thread::spawn(move|| {
         assert_eq!(z.a, 10);
index 4d6edf4ecb0f330522ce374a08209a48c3a10210..429b21e8b8b99b73da84f9840146249a1d702e28 100644 (file)
@@ -5,8 +5,6 @@
 // storing closure data (as we used to do), the u64 would
 // overwrite the u16.
 
-#![feature(box_syntax)]
-
 struct Pair<A,B> {
     a: A, b: B
 }
@@ -27,10 +25,10 @@ fn f(&self) -> (A, u16) {
 }
 
 fn f<A:Clone + 'static>(a: A, b: u16) -> Box<dyn Invokable<A>+'static> {
-    box Invoker {
+    Box::new(Invoker {
         a: a,
         b: b,
-    } as Box<dyn Invokable<A>+'static>
+    }) as Box<dyn Invokable<A>+'static>
 }
 
 pub fn main() {
index 6a8c9664051dfc0e4c9681cbe695e63738adc6c1..5ff7b1242db702666dbcf91cf3c6b1adf17f241a 100644 (file)
@@ -1,10 +1,10 @@
 // edition:2021
 
+
+
 // Tests that two closures cannot simultaneously have mutable
 // and immutable access to the variable. Issue #6801.
 
-#![feature(box_syntax)]
-
 #[derive(Debug)]
 struct Point {
     x: i32,
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs
new file mode 100644 (file)
index 0000000..2f8cddc
--- /dev/null
@@ -0,0 +1,101 @@
+// edition:2021
+
+// Tests that in cases where we individually capture all the fields of a type,
+// we still drop them in the order they would have been dropped in the 2018 edition.
+
+// NOTE: It is *critical* that the order of the min capture NOTES in the stderr output
+//       does *not* change!
+
+#![feature(rustc_attrs)]
+
+#[derive(Debug)]
+struct HasDrop;
+impl Drop for HasDrop {
+    fn drop(&mut self) {
+        println!("dropped");
+    }
+}
+
+fn test_one() {
+    let a = (HasDrop, HasDrop);
+    let b = (HasDrop, HasDrop);
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+        //~^ ERROR: Min Capture analysis includes:
+        //~| ERROR
+        println!("{:?}", a.0);
+        //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", a.1);
+        //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow
+        //~| NOTE
+
+        println!("{:?}", b.0);
+        //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", b.1);
+        //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow
+        //~| NOTE
+    };
+}
+
+fn test_two() {
+    let a = (HasDrop, HasDrop);
+    let b = (HasDrop, HasDrop);
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+        //~^ ERROR: Min Capture analysis includes:
+        //~| ERROR
+        println!("{:?}", a.1);
+        //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", a.0);
+        //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow
+        //~| NOTE
+
+        println!("{:?}", b.1);
+        //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", b.0);
+        //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow
+        //~| NOTE
+    };
+}
+
+fn test_three() {
+    let a = (HasDrop, HasDrop);
+    let b = (HasDrop, HasDrop);
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+        //~^ ERROR: Min Capture analysis includes:
+        //~| ERROR
+        println!("{:?}", b.1);
+        //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", a.1);
+        //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow
+        //~| NOTE
+        println!("{:?}", a.0);
+        //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow
+        //~| NOTE
+
+        println!("{:?}", b.0);
+        //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow
+        //~| NOTE
+    };
+}
+
+fn main() {
+    test_one();
+    test_two();
+    test_three();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr
new file mode 100644 (file)
index 0000000..2d1dc87
--- /dev/null
@@ -0,0 +1,228 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/preserve_field_drop_order.rs:23:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/preserve_field_drop_order.rs:49:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/preserve_field_drop_order.rs:75:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error: First Pass analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:26:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", a.0);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:29:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Capturing a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:32:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+note: Capturing b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:36:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+note: Capturing b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:39:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:26:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", a.0);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:29:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Min Capture a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:32:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+note: Min Capture b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:36:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+note: Min Capture b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:39:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+
+error: First Pass analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:52:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", a.1);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:55:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+note: Capturing a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:58:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Capturing b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:62:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+note: Capturing b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:65:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:52:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", a.1);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:58:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Min Capture a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:55:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+note: Min Capture b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:65:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+note: Min Capture b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:62:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+
+error: First Pass analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:78:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", b.1);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:81:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+note: Capturing a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:84:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+note: Capturing a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:87:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Capturing b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:91:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/preserve_field_drop_order.rs:78:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", b.1);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture b[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:91:26
+   |
+LL |         println!("{:?}", b.0);
+   |                          ^^^
+note: Min Capture b[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:81:26
+   |
+LL |         println!("{:?}", b.1);
+   |                          ^^^
+note: Min Capture a[(0, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:87:26
+   |
+LL |         println!("{:?}", a.0);
+   |                          ^^^
+note: Min Capture a[(1, 0)] -> ImmBorrow
+  --> $DIR/preserve_field_drop_order.rs:84:26
+   |
+LL |         println!("{:?}", a.1);
+   |                          ^^^
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs
new file mode 100644 (file)
index 0000000..1cae776
--- /dev/null
@@ -0,0 +1,58 @@
+// run-pass
+// check-run-results
+// revisions: twenty_eighteen twenty_twentyone
+// [twenty_eighteen]compile-flags: --edition 2018
+// [twenty_twentyone]compile-flags: --edition 2021
+
+#[derive(Debug)]
+struct Dropable(&'static str);
+
+impl Drop for Dropable {
+    fn drop(&mut self) {
+        println!("Dropping {}", self.0)
+    }
+}
+
+#[derive(Debug)]
+struct A {
+    x: Dropable,
+    y: Dropable,
+}
+
+#[derive(Debug)]
+struct B {
+    c: A,
+    d: A,
+}
+
+#[derive(Debug)]
+struct R<'a> {
+    c: &'a A,
+    d: &'a A,
+}
+
+fn main() {
+    let a = A { x: Dropable("x"), y: Dropable("y") };
+
+    let c = move || println!("{:?} {:?}", a.y, a.x);
+
+    c();
+
+    let b = B {
+        c: A { x: Dropable("b.c.x"), y: Dropable("b.c.y") },
+        d: A { x: Dropable("b.d.x"), y: Dropable("b.d.y") },
+    };
+
+    let d = move || println!("{:?} {:?} {:?} {:?}", b.d.y, b.d.x, b.c.y, b.c.x);
+
+    d();
+
+        let r = R {
+        c: &A { x: Dropable("r.c.x"), y: Dropable("r.c.y") },
+        d: &A { x: Dropable("r.d.x"), y: Dropable("r.d.y") },
+    };
+
+    let e = move || println!("{:?} {:?} {:?} {:?}", r.d.y, r.d.x, r.c.y, r.c.x);
+
+    e();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout
new file mode 100644 (file)
index 0000000..557d047
--- /dev/null
@@ -0,0 +1,13 @@
+Dropable("y") Dropable("x")
+Dropable("b.d.y") Dropable("b.d.x") Dropable("b.c.y") Dropable("b.c.x")
+Dropable("r.d.y") Dropable("r.d.x") Dropable("r.c.y") Dropable("r.c.x")
+Dropping r.d.x
+Dropping r.d.y
+Dropping r.c.x
+Dropping r.c.y
+Dropping b.c.x
+Dropping b.c.y
+Dropping b.d.x
+Dropping b.d.y
+Dropping x
+Dropping y
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout
new file mode 100644 (file)
index 0000000..557d047
--- /dev/null
@@ -0,0 +1,13 @@
+Dropable("y") Dropable("x")
+Dropable("b.d.y") Dropable("b.d.x") Dropable("b.c.y") Dropable("b.c.x")
+Dropable("r.d.y") Dropable("r.d.x") Dropable("r.c.y") Dropable("r.c.x")
+Dropping r.d.x
+Dropping r.d.y
+Dropping r.c.x
+Dropping r.c.y
+Dropping b.c.x
+Dropping b.c.y
+Dropping b.d.x
+Dropping b.d.y
+Dropping x
+Dropping y
index d486fdf73aba8d795a1dde8c4ff37ad921efed26..eeb8fe82346c2245dd103e96c0d5aaaacd3fedcc 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(unused_braces)]
-#![feature(box_syntax)]
 
 use std::cell::RefCell;
 use std::fmt::Debug;
diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
new file mode 100644 (file)
index 0000000..fbaa874
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `(): std::error::Error` is not satisfied
+  --> $DIR/coerce-issue-49593-box-never.rs:17:53
+   |
+LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
+   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
+   |
+   = note: required for the cast to the object type `dyn std::error::Error`
+
+error[E0277]: the trait bound `(): std::error::Error` is not satisfied
+  --> $DIR/coerce-issue-49593-box-never.rs:22:49
+   |
+LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
+   |
+   = note: required for the cast to the object type `(dyn std::error::Error + 'static)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
index 0824ce8cd585b68061e13cdddf16e64a302ff048..7a4324bd5adcedd124b9473e4e742cb1ea3fd4e8 100644 (file)
@@ -1,5 +1,9 @@
-// check-pass
-#![feature(never_type, never_type_fallback)]
+// revisions: nofallback fallback
+//[fallback] check-pass
+//[nofallback] check-fail
+
+#![feature(never_type)]
+#![cfg_attr(fallback, feature(never_type_fallback))]
 #![allow(unreachable_code)]
 
 use std::error::Error;
@@ -11,10 +15,12 @@ fn raw_ptr_box<T>(t: T) -> *mut T {
 
 fn foo(x: !) -> Box<dyn Error> {
     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
+    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
 }
 
 fn foo_raw_ptr(x: !) -> *mut dyn Error {
     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
+    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
 }
 
 fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
index 51f6faab3c7e48bde89e253cb8a580fee7f0dfa0..9efb5dc75f4f0dc65b7c8538a78863f8c40c46e0 100644 (file)
@@ -8,6 +8,7 @@ LL | impl<A:Iterator> Foo<A::Item> for A { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
    |
    = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
+   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/issue-89088.rs b/src/test/ui/consts/issue-89088.rs
new file mode 100644 (file)
index 0000000..40cc665
--- /dev/null
@@ -0,0 +1,22 @@
+// Regression test for the ICE described in #89088.
+
+// check-pass
+
+#![allow(indirect_structural_match)]
+use std::borrow::Cow;
+
+const FOO: &A = &A::Field(Cow::Borrowed("foo"));
+
+#[derive(PartialEq, Eq)]
+enum A {
+    Field(Cow<'static, str>)
+}
+
+fn main() {
+    let var = A::Field(Cow::Borrowed("bar"));
+
+    match &var {
+        FOO => todo!(),
+        _ => todo!()
+    }
+}
index 1f0b7f7e78a69dc17766139d0b3dee7df4ccc99d..32796c67229a7eb0892163503d37679d889e9002 100644 (file)
@@ -9,5 +9,5 @@ fn main() {}
 static TEST_BAD: &mut i32 = {
     &mut *(box 0)
     //~^ ERROR could not evaluate static initializer
-    //~| NOTE heap allocations
+    //~| NOTE calling non-const function `alloc::alloc::exchange_malloc`
 };
index 66ea9d5924dfb6157740e1aa7386534e36226f48..05d9858dc09f0a938351136a19bb1cab9d5fde8e 100644 (file)
@@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/box.rs:10:11
    |
 LL |     &mut *(box 0)
-   |           ^^^^^^^ "heap allocations via `box` keyword" needs an rfc before being allowed inside constants
+   |           ^^^^^^^ calling non-const function `alloc::alloc::exchange_malloc`
 
 warning: skipping const checks
    |
diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.rs b/src/test/ui/consts/refs_check_const_eq-issue-88384.rs
new file mode 100644 (file)
index 0000000..204d18e
--- /dev/null
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(fn_traits)]
+#![feature(adt_const_params)]
+//~^ WARNING the feature `adt_const_params` is incomplete
+
+#[derive(PartialEq, Eq)]
+struct CompileTimeSettings{
+    hooks: &'static[fn()],
+}
+
+struct Foo<const T: CompileTimeSettings>;
+
+impl<const T: CompileTimeSettings> Foo<T> {
+    fn call_hooks(){
+    }
+}
+
+fn main(){
+    const SETTINGS: CompileTimeSettings = CompileTimeSettings{
+        hooks: &[],
+    };
+
+    Foo::<SETTINGS>::call_hooks();
+}
diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr
new file mode 100644 (file)
index 0000000..55928b4
--- /dev/null
@@ -0,0 +1,11 @@
+warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/refs_check_const_eq-issue-88384.rs:4:12
+   |
+LL | #![feature(adt_const_params)]
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs b/src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs
new file mode 100644 (file)
index 0000000..6ce9da4
--- /dev/null
@@ -0,0 +1,12 @@
+// check-pass
+
+#![allow(incomplete_features)]
+#![feature(adt_const_params)]
+
+struct FooConst<const ARRAY: &'static [&'static str]> {}
+
+const FOO_ARR: &[&'static str; 2] = &["Hello", "Friend"];
+
+fn main() {
+    let _ = FooConst::<FOO_ARR> {};
+}
index eefcf7738ada779adf96a0d414c88ce9bb978433..55e05cfb203b9c806abf38c654178f7c2b2e9a3e 100644 (file)
@@ -1,8 +1,6 @@
 // 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.
@@ -14,7 +12,7 @@
 pub fn main() {
     use crate_method_reexport_grrrrrrr2::rust::add;
     use crate_method_reexport_grrrrrrr2::rust::cx;
-    let x: Box<_> = box ();
+    let x: Box<_> = Box::new(());
     x.cx();
     let y = ();
     y.add("hi".to_string());
index 379ed076611f4990d7c40e8658c0e4594c772b2a..23d76ef3656e1454427e594e27608876b24c80d8 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 use std::cell::RefCell;
 
 pub struct Entry<A,B> {
@@ -37,7 +35,7 @@ pub fn new_int_alist<B:'static>() -> alist<isize, B> {
     fn eq_int(a: isize, b: isize) -> bool { a == b }
     return alist {
         eq_fn: eq_int,
-        data: box RefCell::new(Vec::new()),
+        data: Box::new(RefCell::new(Vec::new())),
     };
 }
 
@@ -47,6 +45,6 @@ pub fn new_int_alist_2<B:'static>() -> alist<isize, B> {
     fn eq_int(a: isize, b: isize) -> bool { a == b }
     return alist {
         eq_fn: eq_int,
-        data: box RefCell::new(Vec::new()),
+        data: Box::new(RefCell::new(Vec::new())),
     };
 }
index 605a166ffa3564d12c73790ad4ff795022bc03eb..fee6b5d03a9e562ae74825fa1e62c2b41b57d003 100644 (file)
@@ -1,13 +1,11 @@
 // 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 p: Box<_> = Box::new(22);
     let r = foo(&*p);
     println!("r={}", r);
     assert_eq!(r, 22);
index a0ee3ad31e6976f2899f146405ee5ba5454f69d8..978c1994800c901b413b0c1457440ada4965f4af 100644 (file)
@@ -1,7 +1,8 @@
 // Test that when a trait impl changes, fns whose body uses that trait
 // must also be recompiled.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-assoc-type-codegen
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
index 4e659648e9edce5a2d07fdbad3287b57c4b5b8f9..cdc268cff992e0fb94f52f19e01872c2e15bd253 100644 (file)
@@ -1,5 +1,5 @@
 error: OK
-  --> $DIR/dep-graph-assoc-type-codegen.rs:28:5
+  --> $DIR/dep-graph-assoc-type-codegen.rs:29:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index c95ea53650b479b78abbc6dd1344366089d43178..4a3a8bb6bf9394808448c13964ba49141364737f 100644 (file)
@@ -1,7 +1,8 @@
 // Test that immediate callers have to change when callee changes, but
 // not callers' callers.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-caller-callee
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 3d968aa3ea68a79676bc993b6995eebe459228b7..4d06dc7f3ed37250ca205691b0489f0fd4a491b1 100644 (file)
@@ -1,11 +1,11 @@
 error: OK
-  --> $DIR/dep-graph-caller-callee.rs:20:5
+  --> $DIR/dep-graph-caller-callee.rs:21:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `x` to `typeck`
-  --> $DIR/dep-graph-caller-callee.rs:31:5
+  --> $DIR/dep-graph-caller-callee.rs:32:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 50a670b87723826eacd976d93747d085f243f894..fcf9f6387102f64c2012b080b2882ef4f313a3b6 100644 (file)
@@ -1,7 +1,8 @@
 // Test cases where a changing struct appears in the signature of fns
 // and methods.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-struct-signature
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index b81aeabab7ff1b0dc483f4211acfc2fb12c01a5b..60bfbe94a8a8b7055ad4ad41e64842e2a50e63cb 100644 (file)
 error: no path from `WillChange` to `type_of`
-  --> $DIR/dep-graph-struct-signature.rs:27:5
+  --> $DIR/dep-graph-struct-signature.rs:28:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `associated_item`
-  --> $DIR/dep-graph-struct-signature.rs:28:5
+  --> $DIR/dep-graph-struct-signature.rs:29:5
    |
 LL |     #[rustc_then_this_would_need(associated_item)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `trait_def`
-  --> $DIR/dep-graph-struct-signature.rs:29:5
+  --> $DIR/dep-graph-struct-signature.rs:30:5
    |
 LL |     #[rustc_then_this_would_need(trait_def)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:31:9
+  --> $DIR/dep-graph-struct-signature.rs:32:9
    |
 LL |         #[rustc_then_this_would_need(fn_sig)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:35:5
+  --> $DIR/dep-graph-struct-signature.rs:36:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:36:5
+  --> $DIR/dep-graph-struct-signature.rs:37:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:39:5
+  --> $DIR/dep-graph-struct-signature.rs:40:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:40:5
+  --> $DIR/dep-graph-struct-signature.rs:41:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:45:5
+  --> $DIR/dep-graph-struct-signature.rs:46:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:47:9
+  --> $DIR/dep-graph-struct-signature.rs:48:9
    |
 LL |         #[rustc_then_this_would_need(fn_sig)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:48:9
+  --> $DIR/dep-graph-struct-signature.rs:49:9
    |
 LL |         #[rustc_then_this_would_need(typeck)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:52:5
+  --> $DIR/dep-graph-struct-signature.rs:53:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:54:9
+  --> $DIR/dep-graph-struct-signature.rs:55:9
    |
 LL |         #[rustc_then_this_would_need(fn_sig)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:55:9
+  --> $DIR/dep-graph-struct-signature.rs:56:9
    |
 LL |         #[rustc_then_this_would_need(typeck)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:60:9
+  --> $DIR/dep-graph-struct-signature.rs:61:9
    |
 LL |         #[rustc_then_this_would_need(type_of)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-struct-signature.rs:62:9
+  --> $DIR/dep-graph-struct-signature.rs:63:9
    |
 LL |         #[rustc_then_this_would_need(type_of)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `type_of`
-  --> $DIR/dep-graph-struct-signature.rs:67:5
+  --> $DIR/dep-graph-struct-signature.rs:68:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `type_of`
-  --> $DIR/dep-graph-struct-signature.rs:74:5
+  --> $DIR/dep-graph-struct-signature.rs:75:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `fn_sig`
-  --> $DIR/dep-graph-struct-signature.rs:76:9
+  --> $DIR/dep-graph-struct-signature.rs:77:9
    |
 LL |         #[rustc_then_this_would_need(fn_sig)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `fn_sig`
-  --> $DIR/dep-graph-struct-signature.rs:80:5
+  --> $DIR/dep-graph-struct-signature.rs:81:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `fn_sig`
-  --> $DIR/dep-graph-struct-signature.rs:83:5
+  --> $DIR/dep-graph-struct-signature.rs:84:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `WillChange` to `typeck`
-  --> $DIR/dep-graph-struct-signature.rs:84:5
+  --> $DIR/dep-graph-struct-signature.rs:85:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index c0a6617316b8dc9994c991cc5a9e52175262a32a..5da8df57064643a9472fe0177307ab1ad8f7b17d 100644 (file)
@@ -1,7 +1,8 @@
 // Test that adding an impl to a trait `Foo` DOES affect functions
 // that only use `Bar` if they have methods in common.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl-two-traits-same-method
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index ae3d725e1c051a091220df9413487aa5de8d4a85..6f56cbc8dd7ae55d450a42782eb2054c964c0e98 100644 (file)
@@ -1,11 +1,11 @@
 error: OK
-  --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:32:5
+  --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `x::<impl Foo for u32>` to `typeck`
-  --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:41:5
+  --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 56e9762ddb26c1740b55ee185748175e31b97d7c..0331e75b2fe8d6c060d1792508d77cf07033fb6e 100644 (file)
@@ -1,7 +1,8 @@
 // Test that adding an impl to a trait `Foo` does not affect functions
 // that only use `Bar`, so long as they do not have methods in common.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl-two-traits
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
index 4823927477fe08e19ef499997d0498d65dc838ed..08f382cc024c7377830943c77a04ebd0fbb65e83 100644 (file)
@@ -1,11 +1,11 @@
 error: no path from `x::<impl Foo for char>` to `typeck`
-  --> $DIR/dep-graph-trait-impl-two-traits.rs:31:5
+  --> $DIR/dep-graph-trait-impl-two-traits.rs:32:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `x::<impl Foo for char>` to `typeck`
-  --> $DIR/dep-graph-trait-impl-two-traits.rs:40:5
+  --> $DIR/dep-graph-trait-impl-two-traits.rs:41:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 3bbe3e745ca691c7ad266f3946996b82a4ca642a..19002965b93721a6ece38d222e74c19436df86ce 100644 (file)
@@ -1,7 +1,8 @@
 // Test that when a trait impl changes, fns whose body uses that trait
 // must also be recompiled.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
index f8ead80894276400d1de6be0b3c8d8f79a30177c..bfee6d5c87b3452572e1979a6abc5863180426aa 100644 (file)
@@ -1,29 +1,29 @@
 error: OK
-  --> $DIR/dep-graph-trait-impl.rs:27:5
+  --> $DIR/dep-graph-trait-impl.rs:28:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-trait-impl.rs:32:5
+  --> $DIR/dep-graph-trait-impl.rs:33:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-trait-impl.rs:37:5
+  --> $DIR/dep-graph-trait-impl.rs:38:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-trait-impl.rs:42:5
+  --> $DIR/dep-graph-trait-impl.rs:43:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `x::<impl Foo for char>` to `typeck`
-  --> $DIR/dep-graph-trait-impl.rs:55:5
+  --> $DIR/dep-graph-trait-impl.rs:56:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 5c5e24693a4f563039c99a0edc55f840fc613203..0e1b3db192518df08b25fd35267f2ae2037a0f13 100644 (file)
@@ -1,6 +1,7 @@
 // Test that changing what a `type` points to does not go unnoticed.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-type-alias
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index e698ce8f628b4e898947fcd7db2a4fee01120dda..c59cf8014c3d1dfe69a5b9117c2d211b1ac96e63 100644 (file)
@@ -1,71 +1,71 @@
 error: no path from `TypeAlias` to `type_of`
-  --> $DIR/dep-graph-type-alias.rs:17:1
+  --> $DIR/dep-graph-type-alias.rs:18:1
    |
 LL | #[rustc_then_this_would_need(type_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:19:5
+  --> $DIR/dep-graph-type-alias.rs:20:5
    |
 LL |     #[rustc_then_this_would_need(type_of)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `TypeAlias` to `type_of`
-  --> $DIR/dep-graph-type-alias.rs:24:1
+  --> $DIR/dep-graph-type-alias.rs:25:1
    |
 LL | #[rustc_then_this_would_need(type_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:27:9
+  --> $DIR/dep-graph-type-alias.rs:28:9
    |
 LL |         #[rustc_then_this_would_need(type_of)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `TypeAlias` to `type_of`
-  --> $DIR/dep-graph-type-alias.rs:33:1
+  --> $DIR/dep-graph-type-alias.rs:34:1
    |
 LL | #[rustc_then_this_would_need(type_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:35:5
+  --> $DIR/dep-graph-type-alias.rs:36:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: no path from `TypeAlias` to `type_of`
-  --> $DIR/dep-graph-type-alias.rs:41:1
+  --> $DIR/dep-graph-type-alias.rs:42:1
    |
 LL | #[rustc_then_this_would_need(type_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:43:5
+  --> $DIR/dep-graph-type-alias.rs:44:5
    |
 LL |     #[rustc_then_this_would_need(fn_sig)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:44:5
+  --> $DIR/dep-graph-type-alias.rs:45:5
    |
 LL |     #[rustc_then_this_would_need(typeck)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:48:1
+  --> $DIR/dep-graph-type-alias.rs:49:1
    |
 LL | #[rustc_then_this_would_need(type_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:51:1
+  --> $DIR/dep-graph-type-alias.rs:52:1
    |
 LL | #[rustc_then_this_would_need(fn_sig)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: OK
-  --> $DIR/dep-graph-type-alias.rs:52:1
+  --> $DIR/dep-graph-type-alias.rs:53:1
    |
 LL | #[rustc_then_this_would_need(typeck)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 4f1612759559d95bb5e53a3712af6a378545323c..008434696d63ddfc7102070ba97c9c14e7edf58e 100644 (file)
@@ -1,7 +1,8 @@
 // Test that changing what a `type` points to does not go unnoticed
 // by the variance analysis.
 
-// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-variance-alias
+// incremental
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 2422cb9bb2f52ed93695bd62f1a8f2c388299e30..554ff455a2073580156b905e8ed63021bd50bdbf 100644 (file)
@@ -1,5 +1,5 @@
 error: OK
-  --> $DIR/dep-graph-variance-alias.rs:18:1
+  --> $DIR/dep-graph-variance-alias.rs:19:1
    |
 LL | #[rustc_then_this_would_need(variances_of)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index cad4ede06a56175050055610cde6d60d52858039..0d4e08ad95476995f98ae0433d3bdbd8df6875c1 100644 (file)
@@ -1,9 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let x: Box<isize> = box 10;
+    let x: Box<isize> = Box::new(10);
     let _y: isize = *x;
 }
index 237dbfaa0567468910aed5842d2999e74545b4e4..b71e1149613886771665ac017219370b8cec8cbb 100644 (file)
@@ -1,6 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
-
 use std::default::Default;
 
 #[derive(Default)]
index fdc9bbab7306773b2a91190989c4c3092c336adc..50b64aeebf0efadb3904a9b10e10b250d580c7c3 100644 (file)
@@ -2,11 +2,11 @@
 // reference work properly.
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 trait T { fn foo(&self) {} }
 impl T for isize {}
 
+
 fn main() {
     // For an expression of the form:
     //
@@ -25,7 +25,7 @@ fn main() {
     // n == m
     let &x = &1isize as &dyn T;      //~ ERROR type `&dyn T` cannot be dereferenced
     let &&x = &(&1isize as &dyn T);  //~ ERROR type `&dyn T` cannot be dereferenced
-    let box x = box 1isize as Box<dyn T>;
+    let box x = Box::new(1isize) as Box<dyn T>;
     //~^ ERROR type `Box<dyn T>` cannot be dereferenced
 
     // n > m
@@ -37,7 +37,7 @@ fn main() {
     //~^ ERROR mismatched types
     //~| expected trait object `dyn T`
     //~| found reference `&_`
-    let box box x = box 1isize as Box<dyn T>;
+    let box box x = Box::new(1isize) as Box<dyn T>;
     //~^ ERROR mismatched types
     //~| expected trait object `dyn T`
     //~| found struct `Box<_>`
index fb43ca760b8c0b898767444cc3352948028c871e..302917ca02e00ef79f122e47e3d0b86d599820b3 100644 (file)
@@ -13,7 +13,7 @@ LL |     let &&x = &(&1isize as &dyn T);
 error[E0033]: type `Box<dyn T>` cannot be dereferenced
   --> $DIR/destructure-trait-ref.rs:28:9
    |
-LL |     let box x = box 1isize as Box<dyn T>;
+LL |     let box x = Box::new(1isize) as Box<dyn T>;
    |         ^^^^^ type `Box<dyn T>` cannot be dereferenced
 
 error[E0308]: mismatched types
@@ -43,8 +43,8 @@ LL |     let &&&x = &(&1isize as &dyn T);
 error[E0308]: mismatched types
   --> $DIR/destructure-trait-ref.rs:40:13
    |
-LL |     let box box x = box 1isize as Box<dyn T>;
-   |             ^^^^^   ------------------------ this expression has type `Box<dyn T>`
+LL |     let box box x = Box::new(1isize) as Box<dyn T>;
+   |             ^^^^^   ------------------------------ this expression has type `Box<dyn T>`
    |             |
    |             expected trait object `dyn T`, found struct `Box`
    |
index 1747bf029aa334672d86863ea962e0cf845b9991..ef3a90a53a6a0241b85c0afdeab2dfbfabf44fa7 100644 (file)
@@ -2,11 +2,9 @@
 // pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
-#![feature(box_syntax)]
-
 enum t { foo(Box<isize>), }
 
 pub fn main() {
-    let tt = t::foo(box 10);
+    let tt = t::foo(Box::new(10));
     match tt { t::foo(_z) => { } }
 }
index 1bc3b4c157ca8d596e9353cb905d427a5f165756..377027a4fc5f2895cd611b9658d24082cca9493e 100644 (file)
@@ -5,8 +5,6 @@
 // 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 {
@@ -29,7 +27,7 @@ fn drop(&mut self) {
 
 pub fn main() {
     {
-        let x = box Cat {name: 22};
+        let x = Box::new(Cat {name: 22});
         let nyan: Box<dyn Dummy> = x as Box<dyn Dummy>;
     }
     unsafe {
index aec46575f97fc438fe688ffa3e3f0d8e8098fda0..4ab8f733ad75a419981c8a3318a7a4040bdef065 100644 (file)
@@ -4,8 +4,6 @@
 #![allow(unused_variables)]
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
@@ -57,7 +55,7 @@ pub fn main() {
 
     let (sender, receiver) = channel();
     {
-        let v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender);
+        let v = Foo::NestedVariant(Box::new(42), SendOnDrop { sender: sender.clone() }, sender);
     }
     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
@@ -74,10 +72,10 @@ pub fn main() {
     let (sender, receiver) = channel();
     let t = {
         thread::spawn(move|| {
-            let mut v = Foo::NestedVariant(box 42, SendOnDrop {
+            let mut v = Foo::NestedVariant(Box::new(42), SendOnDrop {
                 sender: sender.clone()
             }, sender.clone());
-            v = Foo::NestedVariant(box 42,
+            v = Foo::NestedVariant(Box::new(42),
                                    SendOnDrop { sender: sender.clone() },
                                    sender.clone());
             v = Foo::SimpleVariant(sender.clone());
index 70bcc3de07d29b279962e8d60e3f32d8b2c3288e..c1e45215ad8c4b78a66ed6cce9af9482ebabe587 100644 (file)
@@ -2,7 +2,6 @@
 #![allow(type_alias_bounds)]
 
 #![allow(unused_features)]
-#![feature(box_syntax)]
 #![feature(unsized_tuple_coercion)]
 
 type Fat<T: ?Sized> = (isize, &'static str, T);
index f70a45a1b357456ec7cc4a8522c85cc58f37f707..604ac511290100700875ac32840cd93803d88eb7 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
 #![allow(type_alias_bounds)]
 
-#![feature(box_syntax)]
 #![feature(unsized_tuple_coercion)]
 
 type Fat<T: ?Sized> = (isize, &'static str, T);
@@ -109,7 +108,7 @@ pub fn main() {
     assert_eq!((*f2)[1], 2);
 
     // Nested Box.
-    let f1 : Box<Fat<[isize; 3]>> = box (5, "some str", [1, 2, 3]);
+    let f1 : Box<Fat<[isize; 3]>> = Box::new((5, "some str", [1, 2, 3]));
     foo(&*f1);
     let f2 : Box<Fat<[isize]>> = f1;
     foo(&*f2);
index d081cb2be7ee39820bb146a6c5eab90f85a38ada..14603a2c71fc4e6e47d9d93ac5cf9b4de6952411 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(unused_braces)]
-#![feature(box_syntax)]
 
 fn test_generic<T, F>(expected: Box<T>, eq: F) where T: Clone, F: FnOnce(Box<T>, Box<T>) -> bool {
     let actual: Box<T> = { expected.clone() };
@@ -13,7 +12,7 @@ fn compare_box(b1: Box<bool>, b2: Box<bool>) -> bool {
         println!("{}", *b2);
         return *b1 == *b2;
     }
-    test_generic::<bool, _>(box true, compare_box);
+    test_generic::<bool, _>(Box::new(true), compare_box);
 }
 
 pub fn main() { test_box(); }
index 9362eb86fc30976dd713c7a408d70c05469bce09..7879c144b10923aa9bbf9c1d474afdf76784ee50 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(unused_braces)]
-#![feature(box_syntax)]
 
 fn test_generic<T, F>(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> bool {
     let actual: T = { expected.clone() };
@@ -9,7 +8,7 @@ fn test_generic<T, F>(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> boo
 
 fn test_vec() {
     fn compare_vec(v1: Box<isize>, v2: Box<isize>) -> bool { return v1 == v2; }
-    test_generic::<Box<isize>, _>(box 1, compare_vec);
+    test_generic::<Box<isize>, _>(Box::new(1), compare_vec);
 }
 
 pub fn main() { test_vec(); }
index eff3fd3a15152a78e55d7d38d381d9c037de1ec1..5fa11ad1283b9d7fcb1060e19c3f743c04590249 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
 #![allow(unused_braces)]
-#![feature(box_syntax)]
 
-pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); }
+pub fn main() { let x: Box<_> = { Box::new(100) }; assert_eq!(*x, 100); }
index 509d069d40fecd73c38ff369e61adfcc80fbdb60..86232683549b602463f200038968229346827a86 100644 (file)
@@ -1,10 +1,8 @@
 // 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 };
+    let rs: Box<_> = if true { Box::new(100) } else { Box::new(101) };
     assert_eq!(*rs, 100);
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-closure_track_caller.rs b/src/test/ui/feature-gates/feature-gate-closure_track_caller.rs
new file mode 100644 (file)
index 0000000..a8d63a8
--- /dev/null
@@ -0,0 +1,7 @@
+#![feature(stmt_expr_attributes)]
+#![feature(generators)]
+
+fn main() {
+    let _closure = #[track_caller] || {}; //~ `#[track_caller]` on closures
+    let _generator = #[track_caller] || { yield; }; //~ `#[track_caller]` on closures
+}
diff --git a/src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr b/src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr
new file mode 100644 (file)
index 0000000..ed63d74
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0658]: `#[track_caller]` on closures is currently unstable
+  --> $DIR/feature-gate-closure_track_caller.rs:5:20
+   |
+LL |     let _closure = #[track_caller] || {};
+   |                    ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+   = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+
+error[E0658]: `#[track_caller]` on closures is currently unstable
+  --> $DIR/feature-gate-closure_track_caller.rs:6:22
+   |
+LL |     let _generator = #[track_caller] || { yield; };
+   |                      ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+   = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
index 0c389e1dc57a960403003316ead1dd6a71685c8e..636ac7107e62a6eeafdd08735546a2b159051df3 100644 (file)
@@ -1,17 +1,17 @@
-#![feature(box_syntax)]
-
 fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
 
+
+
 fn main() {
-    let _: () = (box |_: isize| {}) as Box<dyn FnOnce(isize)>;
+    let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
     //~^ ERROR mismatched types
     //~| expected unit type `()`
     //~| found struct `Box<dyn FnOnce(isize)>`
-    let _: () = (box |_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
+    let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
     //~^ ERROR mismatched types
     //~| expected unit type `()`
     //~| found struct `Box<dyn Fn(isize, isize)>`
-    let _: () = (box || -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
+    let _: () = Box::new(|| -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
     //~^ ERROR mismatched types
     //~| expected unit type `()`
     //~| found struct `Box<dyn FnMut() -> isize>`
index f9fb3a0ef267dbfbd50bfe9f30ecb29ad43c4848..ea88e401bed8737e755b53c36a7abc6fdb9ba499 100644 (file)
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/fn-trait-formatting.rs:6:17
    |
-LL |     let _: () = (box |_: isize| {}) as Box<dyn FnOnce(isize)>;
-   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+LL |     let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
+   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
    |            |
    |            expected due to this
    |
@@ -12,8 +12,8 @@ LL |     let _: () = (box |_: isize| {}) as Box<dyn FnOnce(isize)>;
 error[E0308]: mismatched types
   --> $DIR/fn-trait-formatting.rs:10:17
    |
-LL |     let _: () = (box |_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
-   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+LL |     let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
+   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
    |            |
    |            expected due to this
    |
@@ -23,8 +23,8 @@ LL |     let _: () = (box |_: isize, isize| {}) as Box<dyn Fn(isize, isize)>;
 error[E0308]: mismatched types
   --> $DIR/fn-trait-formatting.rs:14:17
    |
-LL |     let _: () = (box || -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
-   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
+LL |     let _: () = Box::new(|| -> isize { unimplemented!() }) as Box<dyn FnMut() -> isize>;
+   |            --   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Box`
    |            |
    |            expected due to this
    |
@@ -41,7 +41,7 @@ LL |     needs_fn(1);
    |
    = help: the trait `Fn<(isize,)>` is not implemented for `{integer}`
 note: required by a bound in `needs_fn`
-  --> $DIR/fn-trait-formatting.rs:3:31
+  --> $DIR/fn-trait-formatting.rs:1:31
    |
 LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
    |                               ^^^^^^^^^^^^^^^^^^ required by this bound in `needs_fn`
index 6fecb4e76da3222f7a5e9e97e8b4ec052bad3056..afc77355ab00a4b072060829a525f189c7ecc5c7 100644 (file)
@@ -2,8 +2,6 @@
 // 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;
@@ -18,7 +16,7 @@ impl Temporary {
     fn do_stuff(&self) -> bool {true}
 }
 
-fn borrow() -> Box<Temporary> { box Temporary }
+fn borrow() -> Box<Temporary> { Box::new(Temporary) }
 
 
 pub fn main() {
index 79e59f76311fd1d8391ce17c903b9e8063bdbd4b..a8ec9391523c7e1b2c2143e4052507dd2543e789 100644 (file)
@@ -20,13 +20,13 @@ error: malformed `feature` attribute input
   --> $DIR/gated-bad-feature.rs:5:1
    |
 LL | #![feature]
-   | ^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
+   | ^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name1, ...)]`
 
 error: malformed `feature` attribute input
   --> $DIR/gated-bad-feature.rs:6:1
    |
 LL | #![feature = "foo"]
-   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name1, ...)]`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/generic-associated-types/issue-88360.rs b/src/test/ui/generic-associated-types/issue-88360.rs
new file mode 100644 (file)
index 0000000..06af3f5
--- /dev/null
@@ -0,0 +1,19 @@
+#![feature(generic_associated_types)]
+
+trait GatTrait {
+    type Gat<'a>;
+
+    fn test(&self) -> Self::Gat<'_>;
+}
+
+trait SuperTrait<T>
+where
+    for<'a> Self: GatTrait<Gat<'a> = &'a T>,
+{
+    fn copy(&self) -> Self::Gat<'_> where T: Copy {
+        *self.test()
+        //~^ mismatched types
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-88360.stderr b/src/test/ui/generic-associated-types/issue-88360.stderr
new file mode 100644 (file)
index 0000000..cfbf3aa
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-88360.rs:14:9
+   |
+LL | trait SuperTrait<T>
+   |                  - this type parameter
+...
+LL |     fn copy(&self) -> Self::Gat<'_> where T: Copy {
+   |                       ------------- expected `&T` because of return type
+LL |         *self.test()
+   |         ^^^^^^^^^^^^
+   |         |
+   |         expected `&T`, found type parameter `T`
+   |         help: consider borrowing here: `&*self.test()`
+   |
+   = note:   expected reference `&T`
+           found type parameter `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index 76a184d8d256a878735d127d6de53b540ed24814..fc138398634d5182977f167e7b1c96bdc19e39a4 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn id<T:Send>(t: T) -> T { return t; }
 
 pub fn main() {
-    let expected: Box<_> = box 100;
+    let expected: Box<_> = Box::new(100);
     let actual = id::<Box<isize>>(expected.clone());
     println!("{}", *actual);
     assert_eq!(*expected, *actual);
index 9b3e1ee02a2af6508fc3924afb1f9a9ad2b7cff9..10d87f9f43d0dbffc4e4418e97b828d2dce14f9a 100644 (file)
@@ -1,9 +1,8 @@
 // run-pass
-#![feature(box_syntax)]
 
 struct Recbox<T> {x: Box<T>}
 
-fn reclift<T>(t: T) -> Recbox<T> { return Recbox {x: box t}; }
+fn reclift<T>(t: T) -> Recbox<T> { return Recbox { x: Box::new(t) }; }
 
 pub fn main() {
     let foo: isize = 17;
index 6cda1c3dc15e1f3c98edbe2ec92505848a2aa079..7e246bce9a10c86b75f8d273966c53e91bad52f0 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f<T>(x: Box<T>) -> Box<T> { return x; }
 
-pub fn main() { let x = f(box 3); println!("{}", *x); }
+pub fn main() {
+    let x = f(Box::new(3));
+    println!("{}", *x);
+}
index 870ff980ec64d0ac897d9b475c6896a3816e6881..851424a11b5c141c31014ad91499928511091fc4 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 trait Foo<T> {
     fn get(&self) -> T;
@@ -16,7 +15,7 @@ fn get(&self) -> isize {
 }
 
 pub fn main() {
-    let x = box S { x: 1 };
+    let x = Box::new(S { x: 1 });
     let y = x as Box<dyn Foo<isize>>;
     assert_eq!(y.get(), 1);
 }
index e1875f0abbe61130080964d1c4c1fa0db03c6783..74f5b701d98a54153ff5e1b95c2ed308b0c5490a 100644 (file)
@@ -1,13 +1,12 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 enum list<T> { cons(Box<T>, Box<list<T>>), nil, }
 
 pub fn main() {
     let _a: list<isize> =
-        list::cons::<isize>(box 10,
-        box list::cons::<isize>(box 12,
-        box list::cons::<isize>(box 13,
-        box list::nil::<isize>)));
+        list::cons::<isize>(Box::new(10),
+        Box::new(list::cons::<isize>(Box::new(12),
+        Box::new(list::cons::<isize>(Box::new(13),
+        Box::new(list::nil::<isize>))))));
 }
index 74ef4eeba8ab70ca4dc9a0a45e663d5f1099faf5..67f2ccdde34a1c4bd3c4b0bbde8ed0bb0d002ca7 100644 (file)
@@ -5,11 +5,10 @@
 // pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 
 enum option<T> { some(Box<T>), none, }
 
 pub fn main() {
-    let mut a: option<isize> = option::some::<isize>(box 10);
+    let mut a: option<isize> = option::some::<isize>(Box::new(10));
     a = option::none::<isize>;
 }
index d36504c75dd9c6e73f46be86659534a8b5cc05bd..2f34712ecfbf375edf11b4b62ea495028997584b 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 struct Triple<T> { x: T, y: T, z: T }
 
-fn box_it<T>(x: Triple<T>) -> Box<Triple<T>> { return box x; }
+fn box_it<T>(x: Triple<T>) -> Box<Triple<T>> { return Box::new(x); }
 
 pub fn main() {
     let x: Box<Triple<isize>> = box_it::<isize>(Triple{x: 1, y: 2, z: 3});
index a31c104d8f58bb4db302e43f000cbf9aa19b7126..634ff14869eb4d371384f31a382a5d4b93a66005 100644 (file)
@@ -34,7 +34,7 @@ note: ...which requires type-checking `cycle1`...
    |
 LL |     send(cycle2().clone());
    |     ^^^^
-   = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
+   = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`...
 note: ...which requires computing type of `cycle2::{opaque#0}`...
   --> $DIR/auto-trait-leak.rs:19:16
    |
@@ -70,7 +70,7 @@ note: ...which requires type-checking `cycle2`...
    |
 LL |     send(cycle1().clone());
    |     ^^^^
-   = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
+   = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`...
    = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle
 note: cycle used when checking item types in top-level module
   --> $DIR/auto-trait-leak.rs:1:1
index 6d6908ef7f63e00249f324209363e72f8aeea90b..ca26252832bcd5b7a7b48209bdee54b40697650a 100644 (file)
@@ -1,6 +1,6 @@
 // error-pattern: reached the recursion limit while auto-dereferencing
 
-#![feature(box_syntax)]
+
 
 use std::ops::Deref;
 
@@ -17,7 +17,7 @@ fn deref(&self) -> &Foo {
 pub fn main() {
     let mut x;
     loop {
-        x = box x;
+        x = Box::new(x);
         x.foo;
         x.bar();
     }
index cbefbf83be0a24da6a88ef87fc33a20e637c1d38..1f26ba30000b43f4619a7f61d7fc6f1b73a8af0d 100644 (file)
@@ -1,13 +1,10 @@
 error[E0308]: mismatched types
   --> $DIR/infinite-autoderef.rs:20:13
    |
-LL |         x = box x;
-   |             ^^^^^ cyclic type of infinite size
-   |
-help: try using a conversion method
-   |
-LL |         x = (box x).to_string();
-   |             +     +++++++++++++
+LL |         x = Box::new(x);
+   |             ^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
+   |             |
+   |             cyclic type of infinite size
 
 error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:25:5
index ed0c600c1d2e75e4044fd53665f04708487ae5db..7f416262dcb8cb253b4cef2641170fcdc020f495 100644 (file)
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 use std::cell::Cell;
 
@@ -58,7 +57,7 @@ fn test_tup() {
 fn test_unique() {
     let i = &Cell::new(0);
     {
-        let _a: Box<_> = box r(i);
+        let _a: Box<_> = Box::new(r(i));
     }
     assert_eq!(i.get(), 1);
 }
@@ -66,9 +65,9 @@ fn test_unique() {
 fn test_unique_rec() {
     let i = &Cell::new(0);
     {
-        let _a: Box<_> = box BoxR {
+        let _a: Box<_> = Box::new(BoxR {
             x: r(i)
-        };
+        });
     }
     assert_eq!(i.get(), 1);
 }
index 608cf3dee5230565fe54ae0c38a221f0a15bef83..c6e48e8b5afbabe46dac3c4666ff3195f0cc419f 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 #![feature(intrinsics)]
 
 mod rusti {
@@ -34,7 +33,7 @@ mod rusti {
 
 pub fn main() {
     unsafe {
-        let mut x: Box<_> = box 1;
+        let mut x: Box<_> = Box::new(1);
 
         assert_eq!(rusti::atomic_load(&*x), 1);
         *x = 5;
index 88ef8182f023875f256ee3565fec838dbdb61b65..50f1a2f25b95d5df556f7e37d086e4349138b889 100644 (file)
@@ -2,6 +2,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 // revisions: mir thir
 // [thir]compile-flags: -Zthir-unsafeck
+// ignore-tidy-linelength
 
 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
 
@@ -114,11 +115,11 @@ fn main() {
 
         test_panic_msg(
             || mem::uninitialized::<*const dyn Send>(),
-            "attempted to leave type `*const dyn std::marker::Send` uninitialized, which is invalid"
+            "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
         );
         test_panic_msg(
             || mem::zeroed::<*const dyn Send>(),
-            "attempted to zero-initialize type `*const dyn std::marker::Send`, which is invalid"
+            "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
         );
 
         /* FIXME(#66151) we conservatively do not error here yet.
@@ -145,12 +146,12 @@ fn main() {
 
         test_panic_msg(
             || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
-            "attempted to leave type `(std::ptr::NonNull<u32>, u32, u32)` uninitialized, \
+            "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
                 which is invalid"
         );
         test_panic_msg(
             || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
-            "attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
+            "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
                 which is invalid"
         );
 
@@ -187,7 +188,7 @@ fn main() {
         );
         test_panic_msg(
             || mem::uninitialized::<ManuallyDrop<LR>>(),
-            "attempted to leave type `std::mem::ManuallyDrop<LR>` uninitialized, which is invalid"
+            "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
         );
 
         // Some things that should work.
diff --git a/src/test/ui/invalid/invalid-crate-type-macro.rs b/src/test/ui/invalid/invalid-crate-type-macro.rs
new file mode 100644 (file)
index 0000000..9ba5e79
--- /dev/null
@@ -0,0 +1,7 @@
+#![crate_type = foo!()] //~ ERROR malformed `crate_type` attribute
+
+macro_rules! foo {
+    () => {"rlib"};
+}
+
+fn main() {}
diff --git a/src/test/ui/invalid/invalid-crate-type-macro.stderr b/src/test/ui/invalid/invalid-crate-type-macro.stderr
new file mode 100644 (file)
index 0000000..c196d42
--- /dev/null
@@ -0,0 +1,8 @@
+error: malformed `crate_type` attribute input
+  --> $DIR/invalid-crate-type-macro.rs:1:1
+   |
+LL | #![crate_type = foo!()]
+   | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
+
+error: aborting due to previous error
+
index 92bed231586f9eacde055fbffa681c9e49d9dbe8..4072a2fa1624a1ebac5b71982fbab5f7a00f6709 100644 (file)
@@ -2,7 +2,7 @@ error: malformed `crate_type` attribute input
   --> $DIR/invalid_crate_type_syntax.rs:2:1
    |
 LL | #![crate_type(lib)]
-   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
index c08f776dbf20a9bb97f7230e4f2e536c0faa25c8..8b0771985dc3fe53cc50dadb2911156ff65cc307 100644 (file)
@@ -1,15 +1,15 @@
-#![feature(box_syntax)]
-
 trait Foo {
 }
 
+
+
 impl<T:Copy> Foo for T {
 }
 
 fn take_param<T:Foo>(foo: &T) { }
 
 fn main() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     take_param(&x);
     //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied
 }
index 4d4d191b6aaee0283d52f099871f3fb148bbea42..5622d65cb175bb1001a27fc9f5c75afd7492170e 100644 (file)
@@ -1,7 +1,7 @@
 // Issue #14061: tests the interaction between generic implementation
 // parameter bounds and trait objects.
 
-#![feature(box_syntax)]
+
 
 use std::marker;
 
@@ -34,7 +34,7 @@ fn foo<'a>() {
 }
 
 fn foo2<'a>() {
-    let t: Box<S<String>> = box S(marker::PhantomData);
+    let t: Box<S<String>> = Box::new(S(marker::PhantomData));
     let a = t as Box<dyn Gettable<String>>;
     //~^ ERROR : Copy` is not satisfied
 }
@@ -42,7 +42,7 @@ fn foo2<'a>() {
 fn foo3<'a>() {
     struct Foo; // does not impl Copy
 
-    let t: Box<S<Foo>> = box S(marker::PhantomData);
+    let t: Box<S<Foo>> = Box::new(S(marker::PhantomData));
     let a: Box<dyn Gettable<Foo>> = t;
     //~^ ERROR : Copy` is not satisfied
 }
index aad693e5b193708149bf63f1d1aa968e5634c134..87d47556bdd2561ad9033507c8b5e2c88b90a7a9 100644 (file)
@@ -3,7 +3,7 @@
 // revisions: curr object_safe_for_dispatch
 
 #![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
-#![feature(box_syntax)]
+
 
 use std::any::Any;
 
@@ -17,13 +17,13 @@ impl<T:Copy> Foo for T {
 fn take_param<T:Foo>(foo: &T) { }
 
 fn a() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     take_param(&x); //[curr]~ ERROR E0277
     //[object_safe_for_dispatch]~^ ERROR E0277
 }
 
 fn b() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     let y = &x;
     let z = &x as &dyn Foo;
     //[curr]~^ ERROR E0038
diff --git a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.rs
new file mode 100644 (file)
index 0000000..52bd813
--- /dev/null
@@ -0,0 +1,27 @@
+// Make sure that an error is reported if the `call` function of the
+// `fn`/`fn_mut` lang item is grossly ill-formed.
+
+#![feature(lang_items)]
+#![feature(no_core)]
+#![no_core]
+
+#[lang = "fn"]
+trait MyFn<T> {
+    const call: i32 = 42;
+    //~^ ERROR: `call` trait item in `fn` lang item must be a function
+}
+
+#[lang = "fn_mut"]
+trait MyFnMut<T> {
+    fn call(i: i32, j: i32) -> i32 { i + j }
+    //~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference
+}
+
+fn main() {
+    let a = || 42;
+    a();
+
+    let mut i = 0;
+    let mut b = || { i += 1; };
+    b();
+}
diff --git a/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr b/src/test/ui/lang-items/fn-fn_mut-call-ill-formed.stderr
new file mode 100644 (file)
index 0000000..82bdae2
--- /dev/null
@@ -0,0 +1,14 @@
+error: `call` trait item in `fn` lang item must be a function
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:10:5
+   |
+LL |     const call: i32 = 42;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: first argument of `call` in `fn_mut` lang item must be a reference
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:16:16
+   |
+LL |     fn call(i: i32, j: i32) -> i32 { i + j }
+   |                ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lang-items/issue-83471.rs b/src/test/ui/lang-items/issue-83471.rs
new file mode 100644 (file)
index 0000000..b32aa03
--- /dev/null
@@ -0,0 +1,23 @@
+// Regression test for the ICE reported in issue #83471.
+
+#![crate_type="lib"]
+#![feature(no_core)]
+#![no_core]
+
+#[lang = "sized"]
+//~^ ERROR: language items are subject to change [E0658]
+trait Sized {}
+
+#[lang = "fn"]
+//~^ ERROR: language items are subject to change [E0658]
+//~| ERROR: `fn` language item must be applied to a trait with 1 generic argument
+trait Fn {
+    fn call(export_name);
+    //~^ ERROR: expected type
+    //~| WARNING: anonymous parameters are deprecated
+    //~| WARNING: this is accepted in the current edition
+}
+fn call_through_fn_trait() {
+    a()
+    //~^ ERROR: cannot find function
+}
diff --git a/src/test/ui/lang-items/issue-83471.stderr b/src/test/ui/lang-items/issue-83471.stderr
new file mode 100644 (file)
index 0000000..c6130bb
--- /dev/null
@@ -0,0 +1,51 @@
+error[E0573]: expected type, found built-in attribute `export_name`
+  --> $DIR/issue-83471.rs:15:13
+   |
+LL |     fn call(export_name);
+   |             ^^^^^^^^^^^ not a type
+
+error[E0425]: cannot find function `a` in this scope
+  --> $DIR/issue-83471.rs:21:5
+   |
+LL |     a()
+   |     ^ not found in this scope
+
+error[E0658]: language items are subject to change
+  --> $DIR/issue-83471.rs:7:1
+   |
+LL | #[lang = "sized"]
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(lang_items)]` to the crate attributes to enable
+
+error[E0658]: language items are subject to change
+  --> $DIR/issue-83471.rs:11:1
+   |
+LL | #[lang = "fn"]
+   | ^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(lang_items)]` to the crate attributes to enable
+
+warning: anonymous parameters are deprecated and will be removed in the next edition.
+  --> $DIR/issue-83471.rs:15:13
+   |
+LL |     fn call(export_name);
+   |             ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name`
+   |
+   = note: `#[warn(anonymous_parameters)]` on by default
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+
+error[E0718]: `fn` language item must be applied to a trait with 1 generic argument
+  --> $DIR/issue-83471.rs:11:1
+   |
+LL | #[lang = "fn"]
+   | ^^^^^^^^^^^^^^
+...
+LL | trait Fn {
+   |         - this trait has 0 generic arguments
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0425, E0573, E0658, E0718.
+For more information about an error, try `rustc --explain E0425`.
index af2308777939e125dca53b3d03ce3658fd76eb7a..1055fe7995ba629e5686933fd5c51f2128f26d1c 100644 (file)
@@ -3,13 +3,11 @@
 #![allow(dead_code)]
 // Make sure #1399 stays fixed
 
-#![feature(box_syntax)]
-
 struct A { a: Box<isize> }
 
 pub fn main() {
     fn invoke<F>(f: F) where F: FnOnce() { f(); }
-    let k: Box<_> = box 22;
+    let k: Box<_> = 22.into();
     let _u = A {a: k.clone()};
     invoke(|| println!("{}", k.clone()) )
 }
index 752081b78f27568f11d3a501e4d8c9068255bb21..322f726156d0c6e91e23f938c41c1ec6e91c4f21 100644 (file)
@@ -1,8 +1,9 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 fn leaky<T>(_t: T) { }
 
-pub fn main() { let x = box 10; leaky::<Box<isize>>(x); }
+pub fn main() {
+    let x = Box::new(10);
+    leaky::<Box<isize>>(x);
+}
diff --git a/src/test/ui/lint/issue-79546-fuel-ice.rs b/src/test/ui/lint/issue-79546-fuel-ice.rs
new file mode 100644 (file)
index 0000000..0e9f540
--- /dev/null
@@ -0,0 +1,8 @@
+// Regression test for the ICE described in #79546.
+
+// compile-flags: --cap-lints=allow -Zfuel=issue79546=0
+// check-pass
+#![crate_name="issue79546"]
+
+struct S;
+fn main() {}
index b3a41a786c1f0961e10dfffc057ea276da0dab49..91b4e509b269efd791789ebcfd645c8dd48b15da 100644 (file)
@@ -14,7 +14,7 @@ error: malformed `deny` attribute input
   --> $DIR/lint-malformed.rs:1:1
    |
 LL | #![deny = "foo"]
-   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#![deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error[E0452]: malformed lint attribute input
   --> $DIR/lint-malformed.rs:2:10
index 7ef18c28c1ab783311f3e3d7f8c7fca8c54b422d..af47d5c072005b814f25907957830f45cdfe1f33 100644 (file)
@@ -1,12 +1,12 @@
 #![allow(dead_code)]
 #![forbid(box_pointers)]
-#![feature(box_syntax)]
+
 
 struct Foo {
     x: Box<isize> //~ ERROR type uses owned
 }
 
 fn main() {
-    let _x : Foo = Foo {x : box 10};
+    let _x: Foo = Foo { x : Box::new(10) };
     //~^ ERROR type uses owned
 }
index 40310f9387455a16338f5437944a3706dee281c7..5ba3969707571acd7dda91698d0a938af5539ce2 100644 (file)
@@ -13,8 +13,8 @@ LL | #![forbid(box_pointers)]
 error: type uses owned (Box type) pointers: Box<isize>
   --> $DIR/lint-owned-heap-memory.rs:10:29
    |
-LL |     let _x : Foo = Foo {x : box 10};
-   |                             ^^^^^^
+LL |     let _x: Foo = Foo { x : Box::new(10) };
+   |                             ^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/must_not_suspend/boxed.rs b/src/test/ui/lint/must_not_suspend/boxed.rs
new file mode 100644 (file)
index 0000000..1f823fc
--- /dev/null
@@ -0,0 +1,25 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    i: i64
+}
+
+
+fn bar() -> Box<Umm> {
+    Box::new(Umm {
+        i: 1
+    })
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+    let _guard = bar(); //~ ERROR boxed `Umm` held across
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/boxed.stderr b/src/test/ui/lint/must_not_suspend/boxed.stderr
new file mode 100644 (file)
index 0000000..edc62b6
--- /dev/null
@@ -0,0 +1,26 @@
+error: boxed `Umm` held across a suspend point, but should not be
+  --> $DIR/boxed.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/boxed.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+  --> $DIR/boxed.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/boxed.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/dedup.rs b/src/test/ui/lint/must_not_suspend/dedup.rs
new file mode 100644 (file)
index 0000000..040fff5
--- /dev/null
@@ -0,0 +1,20 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+struct No {}
+
+async fn shushspend() {}
+
+async fn wheeee<T>(t: T) {
+    shushspend().await;
+    drop(t);
+}
+
+async fn yes() {
+    wheeee(No {}).await; //~ ERROR `No` held across
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/dedup.stderr b/src/test/ui/lint/must_not_suspend/dedup.stderr
new file mode 100644 (file)
index 0000000..542b7a3
--- /dev/null
@@ -0,0 +1,19 @@
+error: `No` held across a suspend point, but should not be
+  --> $DIR/dedup.rs:16:12
+   |
+LL |     wheeee(No {}).await;
+   |     -------^^^^^------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/dedup.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/dedup.rs:16:12
+   |
+LL |     wheeee(No {}).await;
+   |            ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs
new file mode 100644 (file)
index 0000000..1554408
--- /dev/null
@@ -0,0 +1,9 @@
+// edition:2018
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"] //~ ERROR the `#[must_not_suspend]`
+struct Umm {
+    _i: i64
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr
new file mode 100644 (file)
index 0000000..ab20a8b
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: the `#[must_not_suspend]` attribute is an experimental feature
+  --> $DIR/feature-gate-must_not_suspend.rs:3:1
+   |
+LL | #[must_not_suspend = "You gotta use Umm's, ya know?"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+   = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/lint/must_not_suspend/generic.rs b/src/test/ui/lint/must_not_suspend/generic.rs
new file mode 100644 (file)
index 0000000..b3effa0
--- /dev/null
@@ -0,0 +1,20 @@
+// edition:2018
+// run-pass
+//
+// this test shows a case where the lint doesn't fire in generic code
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+struct No {}
+
+async fn shushspend() {}
+
+async fn wheeee<T>(t: T) {
+    shushspend().await;
+    drop(t);
+}
+
+fn main() {
+    let _fut = wheeee(No {});
+}
diff --git a/src/test/ui/lint/must_not_suspend/handled.rs b/src/test/ui/lint/must_not_suspend/handled.rs
new file mode 100644 (file)
index 0000000..8714be6
--- /dev/null
@@ -0,0 +1,28 @@
+// edition:2018
+// run-pass
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    _i: i64
+}
+
+
+fn bar() -> Umm {
+    Umm {
+        _i: 1
+    }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+    {
+        let _guard = bar();
+    }
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/other_items.rs b/src/test/ui/lint/must_not_suspend/other_items.rs
new file mode 100644 (file)
index 0000000..5aa1abb
--- /dev/null
@@ -0,0 +1,8 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend] //~ ERROR attribute should be
+mod inner {}
+
+fn main() {}
diff --git a/src/test/ui/lint/must_not_suspend/other_items.stderr b/src/test/ui/lint/must_not_suspend/other_items.stderr
new file mode 100644 (file)
index 0000000..41c8896
--- /dev/null
@@ -0,0 +1,10 @@
+error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
+  --> $DIR/other_items.rs:5:1
+   |
+LL | #[must_not_suspend]
+   | ^^^^^^^^^^^^^^^^^^^
+LL | mod inner {}
+   | ------------ is not a struct, enum, or trait
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/ref.rs b/src/test/ui/lint/must_not_suspend/ref.rs
new file mode 100644 (file)
index 0000000..738dd9e
--- /dev/null
@@ -0,0 +1,29 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    i: i64
+}
+
+struct Bar {
+    u: Umm,
+}
+
+async fn other() {}
+
+impl Bar {
+    async fn uhoh(&mut self) {
+        let guard = &mut self.u; //~ ERROR `Umm` held across
+
+        other().await;
+
+        *guard = Umm {
+            i: 2
+        }
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/ref.stderr b/src/test/ui/lint/must_not_suspend/ref.stderr
new file mode 100644 (file)
index 0000000..78b44b0
--- /dev/null
@@ -0,0 +1,27 @@
+error: `Umm` held across a suspend point, but should not be
+  --> $DIR/ref.rs:18:26
+   |
+LL |         let guard = &mut self.u;
+   |                          ^^^^^^
+LL | 
+LL |         other().await;
+   |         ------------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/ref.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+  --> $DIR/ref.rs:18:26
+   |
+LL |         let guard = &mut self.u;
+   |                          ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/ref.rs:18:26
+   |
+LL |         let guard = &mut self.u;
+   |                          ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/return.rs b/src/test/ui/lint/must_not_suspend/return.rs
new file mode 100644 (file)
index 0000000..5b1fa5e
--- /dev/null
@@ -0,0 +1,9 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend] //~ ERROR attribute should be
+fn foo() -> i32 {
+    0
+}
+fn main() {}
diff --git a/src/test/ui/lint/must_not_suspend/return.stderr b/src/test/ui/lint/must_not_suspend/return.stderr
new file mode 100644 (file)
index 0000000..fdada85
--- /dev/null
@@ -0,0 +1,12 @@
+error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
+  --> $DIR/return.rs:5:1
+   |
+LL |   #[must_not_suspend]
+   |   ^^^^^^^^^^^^^^^^^^^
+LL | / fn foo() -> i32 {
+LL | |     0
+LL | | }
+   | |_- is not a struct, enum, or trait
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/trait.rs b/src/test/ui/lint/must_not_suspend/trait.rs
new file mode 100644 (file)
index 0000000..6c911cb
--- /dev/null
@@ -0,0 +1,28 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+trait Wow {}
+
+impl Wow for i32 {}
+
+fn r#impl() -> impl Wow {
+    1
+}
+
+fn r#dyn() -> Box<dyn Wow> {
+    Box::new(1)
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+    let _guard1 = r#impl(); //~ ERROR implementer of `Wow` held across
+    let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across
+
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/trait.stderr b/src/test/ui/lint/must_not_suspend/trait.stderr
new file mode 100644 (file)
index 0000000..d19ffdd
--- /dev/null
@@ -0,0 +1,37 @@
+error: implementer of `Wow` held across a suspend point, but should not be
+  --> $DIR/trait.rs:21:9
+   |
+LL |     let _guard1 = r#impl();
+   |         ^^^^^^^
+...
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/trait.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/trait.rs:21:9
+   |
+LL |     let _guard1 = r#impl();
+   |         ^^^^^^^
+
+error: boxed `Wow` trait object held across a suspend point, but should not be
+  --> $DIR/trait.rs:22:9
+   |
+LL |     let _guard2 = r#dyn();
+   |         ^^^^^^^
+LL | 
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/trait.rs:22:9
+   |
+LL |     let _guard2 = r#dyn();
+   |         ^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lint/must_not_suspend/unit.rs b/src/test/ui/lint/must_not_suspend/unit.rs
new file mode 100644 (file)
index 0000000..d3a19f7
--- /dev/null
@@ -0,0 +1,25 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    i: i64
+}
+
+
+fn bar() -> Umm {
+    Umm {
+        i: 1
+    }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+    let _guard = bar(); //~ ERROR `Umm` held across
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/unit.stderr b/src/test/ui/lint/must_not_suspend/unit.stderr
new file mode 100644 (file)
index 0000000..425c076
--- /dev/null
@@ -0,0 +1,26 @@
+error: `Umm` held across a suspend point, but should not be
+  --> $DIR/unit.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/unit.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+  --> $DIR/unit.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/unit.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/must_not_suspend/warn.rs b/src/test/ui/lint/must_not_suspend/warn.rs
new file mode 100644 (file)
index 0000000..50a696b
--- /dev/null
@@ -0,0 +1,25 @@
+// edition:2018
+// run-pass
+#![feature(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    _i: i64
+}
+
+
+fn bar() -> Umm {
+    Umm {
+        _i: 1
+    }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+    let _guard = bar(); //~ WARNING `Umm` held across
+    other().await;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/warn.stderr b/src/test/ui/lint/must_not_suspend/warn.stderr
new file mode 100644 (file)
index 0000000..24f5227
--- /dev/null
@@ -0,0 +1,22 @@
+warning: `Umm` held across a suspend point, but should not be
+  --> $DIR/warn.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+LL |     other().await;
+   |     ------------- the value is held across this suspend point
+   |
+   = note: `#[warn(must_not_suspend)]` on by default
+note: You gotta use Umm's, ya know?
+  --> $DIR/warn.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/warn.rs:20:9
+   |
+LL |     let _guard = bar();
+   |         ^^^^^^
+
+warning: 1 warning emitted
+
index 0ad014e3361b785d85c0d88a6d8c74efcfe9f7ad..4822a9b2c7ff825ec90ea435514fc9f1d25c2cd2 100644 (file)
@@ -1,7 +1,7 @@
 // check-pass
 
-#![feature(box_syntax)]
 #![feature(box_patterns)]
+
 #![warn(unused)] // UI tests pass `-A unused` (#43896)
 
 struct SoulHistory {
@@ -67,7 +67,7 @@ fn main() {
     };
 
     // Boxed struct
-    match box bag {
+    match Box::new(bag) {
         box Large::Suit { case } => {} //~ WARNING unused variable: `case`
     };
 
index 2ac5733b4199b5ec835b9efeb9c287a68ee315fc..cb83d4103dcedd375bd7d3ab2e38f7775d67a9b5 100644 (file)
@@ -3,8 +3,8 @@
 #![allow(non_camel_case_types)]
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 enum list { cons(isize, Box<list>), nil, }
 
-pub fn main() { list::cons(10, box list::cons(11, box list::cons(12, box list::nil))); }
+pub fn main() {
+    list::cons(10, Box::new(list::cons(11, Box::new(list::cons(12, Box::new(list::nil))))));
+}
index 98d12f5747aaeb9f11372a38796fc7b18bac2184..1bc2ea6b9fef6914ef9fb827a028adf0bbceaf8d 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
 fn take(_x: Box<isize>) {}
 
+
 fn main() {
 
-    let x: Box<isize> = box 25;
+    let x: Box<isize> = Box::new(25);
+
     loop {
         take(x); //~ ERROR use of moved value: `x`
     }
index 5ea5c40f2ac97b68d64a46732ff044ec535f6394..7c0e916eddcaa12e55d76996032d737c662b0c80 100644 (file)
@@ -1,9 +1,9 @@
 error[E0382]: use of moved value: `x`
   --> $DIR/liveness-move-call-arg.rs:9:14
    |
-LL |     let x: Box<isize> = box 25;
+LL |     let x: Box<isize> = Box::new(25);
    |         - move occurs because `x` has type `Box<isize>`, which does not implement the `Copy` trait
-LL |     loop {
+...
 LL |         take(x);
    |              ^ value moved here, in previous iteration of loop
 
index eb3288a28e2bccb9ac918d049cfa6c786a449141..064be14d6d28cd13cf7177f7e3d48bc88802aa80 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn main() {
-    let y: Box<isize> = box 42;
+
+    let y: Box<isize> = 42.into();
     let mut x: Box<isize>;
+
     loop {
         println!("{}", y);
         loop {
index 66b6373e450553470e075d56bee8d60b9f359a15..832d4f8fa030f9fae223c2db1c27565e8e40d861 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: use of moved value: `y`
   --> $DIR/liveness-move-in-loop.rs:11:25
    |
-LL |     let y: Box<isize> = box 42;
+LL |     let y: Box<isize> = 42.into();
    |         - move occurs because `y` has type `Box<isize>`, which does not implement the `Copy` trait
 ...
 LL |                     x = y;
index 9f3ebf1362b823fc736e10d3999584a826e2a5dd..7c0cd282c97e007303ad0002563b2563de0f6444 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn main() {
-    let y: Box<isize> = box 42;
+
+    let y: Box<isize> = 42.into();
     let mut x: Box<isize>;
+
     loop {
         println!("{}", y); //~ ERROR borrow of moved value: `y`
         while true { while true { while true { x = y; x.clone(); } } }
index 92e0f372521580cdc942362446c547472c2f1290..6a8f239bd09a8a073862e455e3e15d7631167d78 100644 (file)
@@ -21,7 +21,7 @@ LL |         while true { while true { while true { x = y; x.clone(); } } }
 error[E0382]: borrow of moved value: `y`
   --> $DIR/liveness-move-in-while.rs:7:24
    |
-LL |     let y: Box<isize> = box 42;
+LL |     let y: Box<isize> = 42.into();
    |         - move occurs because `y` has type `Box<isize>`, which does not implement the `Copy` trait
 ...
 LL |         println!("{}", y);
index 5263e293603cdb9ca2395041ef5f82fea631e2d2..46102ca1eb11ebe3d58282e0a63cb881080d1956 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn main() {
-    let x: Box<_> = box 5;
+
+    let x: Box<_> = 5.into();
     let y = x;
+
     println!("{}", *x); //~ ERROR borrow of moved value: `x`
     y.clone();
 }
index 3977a3f4136d28b21f4cafd0672c4eb4d42506f8..292ce013dcc7622aaaa2cce9a285009cbe79b702 100644 (file)
@@ -1,10 +1,11 @@
 error[E0382]: borrow of moved value: `x`
   --> $DIR/liveness-use-after-move.rs:6:20
    |
-LL |     let x: Box<_> = box 5;
+LL |     let x: Box<_> = 5.into();
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 LL |     let y = x;
    |             - value moved here
+LL | 
 LL |     println!("{}", *x);
    |                    ^^ value borrowed here after move
 
diff --git a/src/test/ui/macros/bang-after-name.fixed b/src/test/ui/macros/bang-after-name.fixed
new file mode 100644 (file)
index 0000000..c107ddd
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_macros)]
+
+macro_rules! foo { //~ ERROR macro names aren't followed by a `!`
+    () => {};
+}
+
+fn main() {}
diff --git a/src/test/ui/macros/bang-after-name.rs b/src/test/ui/macros/bang-after-name.rs
new file mode 100644 (file)
index 0000000..7654d8c
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_macros)]
+
+macro_rules! foo! { //~ ERROR macro names aren't followed by a `!`
+    () => {};
+}
+
+fn main() {}
diff --git a/src/test/ui/macros/bang-after-name.stderr b/src/test/ui/macros/bang-after-name.stderr
new file mode 100644 (file)
index 0000000..f609c49
--- /dev/null
@@ -0,0 +1,8 @@
+error: macro names aren't followed by a `!`
+  --> $DIR/bang-after-name.rs:4:17
+   |
+LL | macro_rules! foo! {
+   |                 ^ help: remove the `!`
+
+error: aborting due to previous error
+
index 98744434d4f8c916aadfd9d4838ccfda4580091b..505f6b6f140baa8e9e3578997c9b1076254f756d 100644 (file)
@@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-1.rs:2:1
    |
 LL | #![plugin]
-   | ^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`
+   | ^^^^^^^^^^ help: must be of the form: `#![plugin(name)]`
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
   --> $DIR/malformed-plugin-1.rs:2:1
index 9bf0bf9345c6cccd911fc39dd934b395ba0885f5..52bbd82a3892b15f2c5b07656bf6c078af09bf31 100644 (file)
@@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-2.rs:2:1
    |
 LL | #![plugin="bleh"]
-   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![plugin(name)]`
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
   --> $DIR/malformed-plugin-2.rs:2:1
index 89b57087507c8466a9fc6e5af98d8b0bcafd374d..dc33b961800ea8bf75bc8ecef9780493ab95a9da 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
-
 use std::collections::HashMap;
 
+
+
 trait Map<K, V>
 {
     fn get(&self, k: K) -> V { panic!() }
@@ -12,7 +12,7 @@ impl<K, V> Map<K, V> for HashMap<K, V> {}
 // Test that trait types printed in error msgs include the type arguments.
 
 fn main() {
-    let x: Box<HashMap<isize, isize>> = box HashMap::new();
+    let x: Box<HashMap<isize, isize>> = HashMap::new().into();
     let x: Box<dyn Map<isize, isize>> = x;
     let y: Box<dyn Map<usize, isize>> = Box::new(x);
     //~^ ERROR `Box<dyn Map<isize, isize>>: Map<usize, isize>` is not satisfied
index 8258fdd9ab93a8eaaa432329c5a6c01fb3233cd3..f89019fe5859f91d3ec691309de635bfcd7fa1cf 100644 (file)
@@ -1,7 +1,5 @@
 #![crate_type = "lib"]
 
-#![feature(box_syntax)]
-
 static mut COUNT: u64 = 1;
 
 pub fn get_count() -> u64 { unsafe { COUNT } }
@@ -19,8 +17,8 @@ pub fn foo(self, x: &Foo) {
         Foo::baz(self);
         Foo::baz(*x);
 
-        Foo::qux(box self);
-        Foo::qux(box *x);
+        Foo::qux(Box::new(self));
+        Foo::qux(Box::new(*x));
     }
 
     pub fn bar(&self) {
index 94a4a016c3eca390fd67cfa8fe6d32571f075d77..96725456291ea0916608aeb7e008ef6d1ce4600a 100644 (file)
@@ -1,7 +1,5 @@
 #![crate_type = "lib"]
 
-#![feature(box_syntax)]
-
 static mut COUNT: u64 = 1;
 
 pub fn get_count() -> u64 { unsafe { COUNT } }
@@ -15,11 +13,11 @@ pub fn run_trait(self) {
         // Test internal call.
         Bar::foo1(&self);
         Bar::foo2(self);
-        Bar::foo3(box self);
+        Bar::foo3(Box::new(self));
 
         Bar::bar1(&self);
         Bar::bar2(self);
-        Bar::bar3(box self);
+        Bar::bar3(Box::new(self));
     }
 }
 
index 9e38ff7de34247c48cfbd38049d69c062f2765ee..79b70a17ca1870d1cebd4a903c5681a85c650e48 100644 (file)
@@ -1,8 +1,6 @@
 // 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;
@@ -12,7 +10,7 @@ fn main() {
     // Test external call.
     Foo::bar(&x);
     Foo::baz(x);
-    Foo::qux(box x);
+    Foo::qux(Box::new(x));
 
     x.foo(&x);
 
index 8e70399d047cd3719affa21a68de96fa27cee871..16487b54f174f550262dbadbdf1137310e61e9d8 100644 (file)
@@ -1,8 +1,6 @@
 // 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};
@@ -12,11 +10,11 @@ fn main() {
     // Test external call.
     Bar::foo1(&x);
     Bar::foo2(x);
-    Bar::foo3(box x);
+    Bar::foo3(Box::new(x));
 
     Bar::bar1(&x);
     Bar::bar2(x);
-    Bar::bar3(box x);
+    Bar::bar3(Box::new(x));
 
     x.run_trait();
 
index 227b1eab25de296239a84db4b7251e2acf92b6c5..ffa7a552b25a3678e056b091f3e6be176de4dc49 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // Test method calls with self as an argument
 
-#![feature(box_syntax)]
-
 static mut COUNT: u64 = 1;
 
 #[derive(Copy, Clone)]
@@ -44,11 +42,11 @@ fn baz(self) {
         // Test internal call.
         Bar::foo1(&self);
         Bar::foo2(self);
-        Bar::foo3(box self);
+        Bar::foo3(Box::new(self));
 
         Bar::bar1(&self);
         Bar::bar2(self);
-        Bar::bar3(box self);
+        Bar::bar3(Box::new(self));
     }
 }
 
@@ -57,11 +55,11 @@ fn main() {
     // Test external call.
     Bar::foo1(&x);
     Bar::foo2(x);
-    Bar::foo3(box x);
+    Bar::foo3(Box::new(x));
 
     Bar::bar1(&x);
     Bar::bar2(x);
-    Bar::bar3(box x);
+    Bar::bar3(Box::new(x));
 
     x.baz();
 
index 2d25b0dbad1967a745e98ce4961bb44caf3f0232..f738fa19c852a0df39d3adb87cd81b061f3d75ab 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // Test method calls with self as an argument
 
-#![feature(box_syntax)]
-
 static mut COUNT: usize = 1;
 
 #[derive(Copy, Clone)]
@@ -18,8 +16,8 @@ fn foo(self, x: &Foo) {
         Foo::baz(self);
         Foo::baz(*x);
 
-        Foo::qux(box self);
-        Foo::qux(box *x);
+        Foo::qux(Box::new(self));
+        Foo::qux(Box::new(*x));
     }
 
     fn bar(&self) {
@@ -40,7 +38,7 @@ fn main() {
     // Test external call.
     Foo::bar(&x);
     Foo::baz(x);
-    Foo::qux(box x);
+    Foo::qux(Box::new(x));
 
     x.foo(&x);
 
index 8af3dcf5c3db01b3c2b40db9db4e5083afd47182..fc5766da9714b807881ef5a1836eba390dc7bbc6 100644 (file)
@@ -10,8 +10,6 @@
 // codegen the call as `Foo::foo(&x)` and let the specific impl get
 // chosen later.
 
-#![feature(box_syntax)]
-
 trait Foo {
     fn foo(&self) -> isize;
 }
@@ -37,7 +35,7 @@ fn call_foo_copy() -> isize {
 fn call_foo_other() -> isize {
     let mut x: Vec<_> = Vec::new();
     let y = x.foo();
-    let z: Box<i32> = box 0;
+    let z: Box<i32> = Box::new(0);
     x.push(z);
     y
 }
diff --git a/src/test/ui/modules/path-invalid-form.rs b/src/test/ui/modules/path-invalid-form.rs
new file mode 100644 (file)
index 0000000..713ef4a
--- /dev/null
@@ -0,0 +1,4 @@
+#[path = 123]  //~ ERROR malformed `path` attribute
+mod foo;
+
+fn main() {}
diff --git a/src/test/ui/modules/path-invalid-form.stderr b/src/test/ui/modules/path-invalid-form.stderr
new file mode 100644 (file)
index 0000000..7e8aa44
--- /dev/null
@@ -0,0 +1,8 @@
+error: malformed `path` attribute input
+  --> $DIR/path-invalid-form.rs:1:1
+   |
+LL | #[path = 123]
+   | ^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/modules/path-macro.rs b/src/test/ui/modules/path-macro.rs
new file mode 100644 (file)
index 0000000..ce2d1e2
--- /dev/null
@@ -0,0 +1,8 @@
+macro_rules! foo {
+    () => {"bar.rs"};
+}
+
+#[path = foo!()] //~ ERROR malformed `path` attribute
+mod abc;
+
+fn main() {}
diff --git a/src/test/ui/modules/path-macro.stderr b/src/test/ui/modules/path-macro.stderr
new file mode 100644 (file)
index 0000000..9a2e01e
--- /dev/null
@@ -0,0 +1,8 @@
+error: malformed `path` attribute input
+  --> $DIR/path-macro.rs:5:1
+   |
+LL | #[path = foo!()]
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+
+error: aborting due to previous error
+
index 7d3987f65608715ce3147fdbf44295120869b968..f98d075d18bba9204103aff0e7a5e1b66a083d8d 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 #[derive(Clone)]
 struct Triple {
@@ -13,12 +12,12 @@ struct Triple {
 fn test(x: bool, foo: Box<Triple>) -> isize {
     let bar = foo;
     let mut y: Box<Triple>;
-    if x { y = bar; } else { y = box Triple{x: 4, y: 5, z: 6}; }
+    if x { y = bar; } else { y = Box::new(Triple{x: 4, y: 5, z: 6}); }
     return y.y;
 }
 
 pub fn main() {
-    let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
+    let x: Box<_> = Box::new(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);
index 910a88c102f0fe37f06a2f3d1d6dee08bdb949eb..8fda3c1c86c6039d2b768f37a6f747e82840aa72 100644 (file)
@@ -1,11 +1,10 @@
 // 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 x: Box<_> = Box::new(X {x: 1, y: 2, z: 3});
     let y = x;
     assert_eq!(y.y, 2);
 }
index 4ad53e96e50f2d1cd9596a54efc525fdc061312d..5e010087465d9e1902eab6cd2d0133ceeccd104c 100644 (file)
@@ -1,7 +1,6 @@
 // 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); }
+pub fn main() { let x: Box<_> = Box::new(X {x: 1, y: 2, z: 3}); let y = x; assert_eq!(y.y, 2); }
index d23a852433f4f9b478312061d6a78d16a9eacc5c..8e5df2c3ff9fd6e93a155707545df7e77608f091 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 #[derive(Clone)]
 struct Triple {
@@ -13,12 +12,12 @@ struct Triple {
 fn test(x: bool, foo: Box<Triple>) -> isize {
     let bar = foo;
     let mut y: Box<Triple>;
-    if x { y = bar; } else { y = box Triple {x: 4, y: 5, z: 6}; }
+    if x { y = bar; } else { y = Box::new(Triple {x: 4, y: 5, z: 6}); }
     return y.y;
 }
 
 pub fn main() {
-    let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
+    let x: Box<_> = Box::new(Triple{x: 1, y: 2, z: 3});
     for _ in 0_usize..10000_usize {
         assert_eq!(test(true, x.clone()), 2);
     }
index 1787caadb7ab0d68ba3c405f0b2e3bc29765593d..24aec7ea62c8b59635d85078ee3d18653309efbb 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 struct Triple {a: isize, b: isize, c: isize}
 
@@ -13,7 +12,7 @@ fn test(foo: Box<Triple>) -> Box<Triple> {
 }
 
 pub fn main() {
-    let x = box Triple{a: 1, b: 2, c: 3};
+    let x = Box::new(Triple{a: 1, b: 2, c: 3});
     let y = test(x);
     assert_eq!(y.c, 3);
 }
index c87c605df7730301edb975436e3eab0d98586044..63aa031a66e60137c09412eb85d38af3a37372a8 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 struct Triple { a: isize, b: isize, c: isize }
 
@@ -13,7 +12,7 @@ fn test(foo: Box<Triple>) -> Box<Triple> {
 }
 
 pub fn main() {
-    let x = box Triple{a: 1, b: 2, c: 3};
+    let x = Box::new(Triple{ a: 1, b: 2, c: 3 });
     let y = test(x);
     assert_eq!(y.c, 3);
 }
index fcfd5e14765f57e50e9f0211a4cc03fbd8bd7660..9622c83750d3ed1b12deea187869ade8eaddfb7b 100644 (file)
@@ -1,13 +1,12 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn test(foo: Box<Vec<isize>> ) { assert_eq!((*foo)[0], 10); }
 
 pub fn main() {
-    let x = box vec![10];
+    let x = Box::new(vec![10]);
     // Test forgetting a local by move-in
     test(x);
 
     // Test forgetting a temporary by move-in.
-    test(box vec![10]);
+    test(Box::new(vec![10]));
 }
index 4cd1f6fe8105e0765f7314287b819ebae794537b..77ee06e192e73c17fc00915b211a850e9830a257 100644 (file)
@@ -1,13 +1,12 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn test(foo: Box<Vec<isize>>) { assert_eq!((*foo)[0], 10); }
 
 pub fn main() {
-    let x = box vec![10];
+    let x = Box::new(vec![10]);
     // Test forgetting a local by move-in
     test(x);
 
     // Test forgetting a temporary by move-in.
-    test(box vec![10]);
+    test(Box::new(vec![10]));
 }
index da436b89f538e511d0a6339f33594c201e6ce21e..b96ef8e19eb51a4fcf3d12413779267ab03fb587 100644 (file)
@@ -8,10 +8,10 @@
 // that assumption did not hold, at least not in the long run (namely,
 // overlapping patterns were turned into warnings rather than errors).
 
-#![feature(box_syntax)]
+
 
 fn main() {
-    let x: Box<_> = box 1;
+    let x: Box<_> = Box::new(1);
 
     let v = (1, 2);
 
index 5fc8a5499326e68e4e76bc148c788862b40aaf4b..2048fefefa31b69855cdbc0df73befa07709c375 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: use of moved value: `x`
   --> $DIR/move-guard-same-consts.rs:20:24
    |
-LL |     let x: Box<_> = box 1;
+LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (1, 2) if take(x) => (),
index 9c50782e6406cf5109180d7f66e1ca59b88194a9..36e39fea6af3b7ef308efb23dc829c89ce2edaca 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
-
 pub fn main() {
-    let x: Box<_> = box 1;
+
+
+    let x: Box<_> = Box::new(1);
 
     let v = (1, 2);
 
index d894209f51764f78af592da8ffc78ce2ec621abf..5e9aa66b90daebd6e4fc9d343e640ef009aa194f 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: use of moved value: `x`
   --> $DIR/move-in-guard-1.rs:10:24
    |
-LL |     let x: Box<_> = box 1;
+LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (1, _) if take(x) => (),
index f478625a83b3efc28ca0b89b55bdfc24d778089b..085b7ec6e0ccc14d5110c46bd13f014c3e275dc7 100644 (file)
@@ -1,7 +1,5 @@
-#![feature(box_syntax)]
-
 pub fn main() {
-    let x: Box<_> = box 1;
+    let x: Box<_> = Box::new(1);
 
     let v = (1, 2);
 
index a067d43389378258d5435d6e858a90a1dc0a935e..ea350926b1519f77a1264274880d4dda57509274 100644 (file)
@@ -1,7 +1,7 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-in-guard-2.rs:10:24
+  --> $DIR/move-in-guard-2.rs:8:24
    |
-LL |     let x: Box<_> = box 1;
+LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (_, 2) if take(x) => (),
index e5a505bb88d328bef7de2ffc33b6dbc343b17b25..66912fa4d099809b8c9901f7906f6c5552b6822e 100644 (file)
@@ -1,13 +1,13 @@
-#![feature(box_syntax)]
-
 struct Foo(Box<isize>);
 
+
+
 fn main() {
-    let x: (Box<_>,) = (box 1,);
+    let x: (Box<_>,) = (Box::new(1),);
     let y = x.0;
     let z = x.0; //~ ERROR use of moved value: `x.0`
 
-    let x = Foo(box 1);
+    let x = Foo(Box::new(1));
     let y = x.0;
     let z = x.0; //~ ERROR use of moved value: `x.0`
 }
index 085e249c0fb073d6bb180fcad3ab2eba648009d8..eca33167f454ae6ea9ee7777c1c45a6815a86a0f 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
+
 
 struct S {
     x: Box<E>
@@ -16,7 +16,7 @@ fn f<G>(s: &S, g: G) where G: FnOnce(&S) {
 }
 
 fn main() {
-    let s = S { x: box E::Bar(box 42) };
+    let s = S { x: Box::new(E::Bar(Box::new(42))) };
     loop {
         f(&s, |hellothere| {
             match hellothere.x { //~ ERROR cannot move out
index 52a5103865123ee44050b604fef98485eb820ef6..76b7aab542de8313d351541b229dbe5b127311c5 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
 
 fn test(_x: Box<usize>) {}
 
 fn main() {
-    let i = box 3;
+    let i = Box::new(3);
     let _f = to_fn(|| test(i)); //~ ERROR cannot move out
 }
index e12af2d45274315fcdef2ad9bfed6f3d1e4f2784..ce930eee2e919a8d336317f87d15aa2b7fc86c53 100644 (file)
@@ -1,7 +1,7 @@
 error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
   --> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:9:28
    |
-LL |     let i = box 3;
+LL |     let i = Box::new(3);
    |         - captured outer variable
 LL |     let _f = to_fn(|| test(i));
    |                    --------^-
index 828d90cd7ac7f4b48c4e2212c388e0e0a920cd0e..2e67d8f8a69131676f12d6c84b356d0111a613af 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
 fn dup(x: Box<isize>) -> Box<(Box<isize>,Box<isize>)> {
-    box (x, x)
+
+
+    Box::new((x, x))
     //~^ use of moved value: `x` [E0382]
 }
 
 fn main() {
-    dup(box 3);
+    dup(Box::new(3));
 }
index a52c023e202930b3e8e61b2b1d6163e59141103a..eef8ce61fa9d8aef6b354c247696b3daa9c471fe 100644 (file)
@@ -1,12 +1,13 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/moves-based-on-type-tuple.rs:4:13
+  --> $DIR/moves-based-on-type-tuple.rs:4:18
    |
 LL | fn dup(x: Box<isize>) -> Box<(Box<isize>,Box<isize>)> {
    |        - move occurs because `x` has type `Box<isize>`, which does not implement the `Copy` trait
-LL |     box (x, x)
-   |          -  ^ value used here after move
-   |          |
-   |          value moved here
+...
+LL |     Box::new((x, x))
+   |               -  ^ value used here after move
+   |               |
+   |               value moved here
 
 error: aborting due to previous error
 
index e620e5de92320fe89928f9b0dee340c145a5dd99..72957c49fc8ae9f7e0e1fb858acc20fb9ff27f74 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
-
 type Noncopyable = Box<isize>;
 
+
+
 struct Foo {
     copied: isize,
     moved: Box<isize>,
@@ -10,8 +10,8 @@ struct Foo {
 
 fn test0(f: Foo, g: Noncopyable, h: Noncopyable) {
     // just copy implicitly copyable fields from `f`, no moves:
-    let _b = Foo {moved: box 1, noncopyable: g, ..f};
-    let _c = Foo {moved: box 2, noncopyable: h, ..f};
+    let _b = Foo {moved: Box::new(1), noncopyable: g, ..f};
+    let _c = Foo {moved: Box::new(2), noncopyable: h, ..f};
 }
 
 fn test1(f: Foo, g: Noncopyable, h: Noncopyable) {
index 620d00edbbce3609e767c103098ad62e2d5b8439..1e682fc4b66c41ec3c8602627e5746a715192a93 100644 (file)
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(box_syntax)]
-
 fn f(mut y: Box<isize>) {
     *y = 5;
     assert_eq!(*y, 5);
@@ -9,13 +7,13 @@ fn f(mut y: Box<isize>) {
 
 fn g() {
     let frob = |mut q: Box<isize>| { *q = 2; assert_eq!(*q, 2); };
-    let w = box 37;
+    let w = Box::new(37);
     frob(w);
 
 }
 
 pub fn main() {
-    let z = box 17;
+    let z = Box::new(17);
     f(z);
     g();
 }
index 63e49c292eac705ee1267b86813aeebd11350c27..080faab73261925d810a1b1ede3cd465c07538ad 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn f(_: &mut isize) {}
 
 fn main() {
-    let mut x: Box<_> = box 3;
+
+    let mut x: Box<_> = Box::new(3);
+
     f(x)    //~ ERROR mismatched types
 }
diff --git a/src/test/ui/never_type/defaulted-never-note.fallback.stderr b/src/test/ui/never_type/defaulted-never-note.fallback.stderr
new file mode 100644 (file)
index 0000000..588d644
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
+  --> $DIR/defaulted-never-note.rs:30:5
+   |
+LL |     foo(_x);
+   |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
+   |
+   = note: this trait is implemented for `()`.
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information).
+   = help: did you intend to use the type `()` here instead?
+note: required by a bound in `foo`
+  --> $DIR/defaulted-never-note.rs:25:11
+   |
+LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
index 70333c5f324f7051831b30f038ef305eb62ab685..54f551759cb3926f9cf7cdf02865e6c171bd64ff 100644 (file)
@@ -1,6 +1,10 @@
+// revisions: nofallback fallback
+//[nofallback] run-pass
+//[fallback] check-fail
+
 // We need to opt into the `never_type_fallback` feature
 // to trigger the requirement that this is testing.
-#![feature(never_type, never_type_fallback)]
+#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
 
 #![allow(unused)]
 
@@ -19,16 +23,16 @@ trait ImplementedForUnitButNotNever {}
 impl ImplementedForUnitButNotNever for () {}
 
 fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-//~^ NOTE required by this bound in `foo`
-//~| NOTE required by a bound in `foo`
+//[fallback]~^ NOTE required by this bound in `foo`
+//[fallback]~| NOTE required by a bound in `foo`
 fn smeg() {
     let _x = return;
     foo(_x);
-    //~^ ERROR the trait bound
-    //~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
-    //~| NOTE this trait is implemented for `()`
-    //~| NOTE this error might have been caused
-    //~| HELP did you intend
+    //[fallback]~^ ERROR the trait bound
+    //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
+    //[fallback]~| NOTE this trait is implemented for `()`
+    //[fallback]~| NOTE this error might have been caused
+    //[fallback]~| HELP did you intend
 }
 
 fn main() {
diff --git a/src/test/ui/never_type/defaulted-never-note.stderr b/src/test/ui/never_type/defaulted-never-note.stderr
deleted file mode 100644 (file)
index 109a81a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
-  --> $DIR/defaulted-never-note.rs:26:5
-   |
-LL |     foo(_x);
-   |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
-   |
-   = note: this trait is implemented for `()`.
-   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information).
-   = help: did you intend to use the type `()` here instead?
-note: required by a bound in `foo`
-  --> $DIR/defaulted-never-note.rs:21:11
-   |
-LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
index ea4881049d7921e756662aa323b7237753b2f069..45a3362fa6d8ea07dc6eab46c26da2bbe14182ba 100644 (file)
@@ -1,30 +1,28 @@
+// revisions: nofallback fallback
 // run-pass
 
 #![allow(dead_code)]
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 #![allow(unreachable_code)]
-
 // Test various cases where we permit an unconstrained variable
-// to fallback based on control-flow.
-//
-// These represent current behavior, but are pretty dubious.  I would
-// like to revisit these and potentially change them. --nmatsakis
-
-#![feature(never_type, never_type_fallback)]
+// to fallback based on control-flow. In all of these cases,
+// the type variable winds up being the target of both a `!` coercion
+// and a coercion from a non-`!` variable, and hence falls back to `()`.
+#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
 
-trait BadDefault {
+trait UnitDefault {
     fn default() -> Self;
 }
 
-impl BadDefault for u32 {
+impl UnitDefault for u32 {
     fn default() -> Self {
         0
     }
 }
 
-impl BadDefault for ! {
-    fn default() -> ! {
+impl UnitDefault for () {
+    fn default() -> () {
         panic!()
     }
 }
@@ -33,7 +31,7 @@ fn assignment() {
     let x;
 
     if true {
-        x = BadDefault::default();
+        x = UnitDefault::default();
     } else {
         x = return;
     }
@@ -45,13 +43,13 @@ fn assignment_rev() {
     if true {
         x = return;
     } else {
-        x = BadDefault::default();
+        x = UnitDefault::default();
     }
 }
 
 fn if_then_else() {
     let _x = if true {
-        BadDefault::default()
+        UnitDefault::default()
     } else {
         return;
     };
@@ -61,19 +59,19 @@ fn if_then_else_rev() {
     let _x = if true {
         return;
     } else {
-        BadDefault::default()
+        UnitDefault::default()
     };
 }
 
 fn match_arm() {
-    let _x = match Ok(BadDefault::default()) {
+    let _x = match Ok(UnitDefault::default()) {
         Ok(v) => v,
         Err(()) => return,
     };
 }
 
 fn match_arm_rev() {
-    let _x = match Ok(BadDefault::default()) {
+    let _x = match Ok(UnitDefault::default()) {
         Err(()) => return,
         Ok(v) => v,
     };
@@ -84,7 +82,7 @@ fn loop_break() {
         if false {
             break return;
         } else {
-            break BadDefault::default();
+            break UnitDefault::default();
         }
     };
 }
@@ -94,9 +92,9 @@ fn loop_break_rev() {
         if false {
             break return;
         } else {
-            break BadDefault::default();
+            break UnitDefault::default();
         }
     };
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr
new file mode 100644 (file)
index 0000000..3a5b602
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `!: Test` is not satisfied
+  --> $DIR/diverging-fallback-no-leak.rs:17:5
+   |
+LL |     unconstrained_arg(return);
+   |     ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!`
+   |
+   = note: this trait is implemented for `()`.
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information).
+   = help: did you intend to use the type `()` here instead?
+note: required by a bound in `unconstrained_arg`
+  --> $DIR/diverging-fallback-no-leak.rs:12:25
+   |
+LL | fn unconstrained_arg<T: Test>(_: T) {}
+   |                         ^^^^ required by this bound in `unconstrained_arg`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.rs b/src/test/ui/never_type/diverging-fallback-no-leak.rs
new file mode 100644 (file)
index 0000000..03478e1
--- /dev/null
@@ -0,0 +1,19 @@
+// revisions: nofallback fallback
+//[nofallback] check-pass
+
+#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
+
+fn make_unit() {}
+
+trait Test {}
+impl Test for i32 {}
+impl Test for () {}
+
+fn unconstrained_arg<T: Test>(_: T) {}
+
+fn main() {
+    // Here the type variable falls back to `!`,
+    // and hence we get a type error.
+    unconstrained_arg(return);
+    //[fallback]~^ ERROR trait bound `!: Test` is not satisfied
+}
diff --git a/src/test/ui/never_type/diverging-fallback-unconstrained-return.rs b/src/test/ui/never_type/diverging-fallback-unconstrained-return.rs
new file mode 100644 (file)
index 0000000..7ea9712
--- /dev/null
@@ -0,0 +1,37 @@
+// Variant of diverging-falllback-control-flow that tests
+// the specific case of a free function with an unconstrained
+// return type. This captures the pattern we saw in the wild
+// in the objc crate, where changing the fallback from `!` to `()`
+// resulted in unsoundness.
+//
+// check-pass
+
+// revisions: nofallback fallback
+
+#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
+
+
+fn make_unit() {}
+
+trait UnitReturn {}
+impl UnitReturn for i32 {}
+impl UnitReturn for () {}
+
+fn unconstrained_return<T: UnitReturn>() -> T {
+    unsafe {
+        let make_unit_fn: fn() = make_unit;
+        let ffi: fn() -> T = std::mem::transmute(make_unit_fn);
+        ffi()
+    }
+}
+
+fn main() {
+    // In Ye Olde Days, the `T` parameter of `unconstrained_return`
+    // winds up "entangled" with the `!` type that results from
+    // `panic!`, and hence falls back to `()`. This is kind of unfortunate
+    // and unexpected. When we introduced the `!` type, the original
+    // idea was to change that fallback to `!`, but that would have resulted
+    // in this code no longer compiling (or worse, in some cases it injected
+    // unsound results).
+    let _ = if true { unconstrained_return() } else { panic!() };
+}
diff --git a/src/test/ui/never_type/fallback-closure-ret.rs b/src/test/ui/never_type/fallback-closure-ret.rs
new file mode 100644 (file)
index 0000000..5c8ce48
--- /dev/null
@@ -0,0 +1,23 @@
+// This test verifies that never type fallback preserves the following code in a
+// compiling state. This pattern is fairly common in the wild, notably seen in
+// wasmtime v0.16. Typically this is some closure wrapper that expects a
+// collection of 'known' signatures, and -> ! is not included in that set.
+//
+// This test is specifically targeted by the unit type fallback when
+// encountering a set of obligations like `?T: Foo` and `Trait::Projection =
+// ?T`. In the code below, these are `R: Bar` and `Fn::Output = R`.
+//
+// revisions: nofallback fallback
+// check-pass
+
+#![cfg_attr(fallback, feature(never_type_fallback))]
+
+trait Bar { }
+impl Bar for () {  }
+impl Bar for u32 {  }
+
+fn foo<R: Bar>(_: impl Fn() -> R) {}
+
+fn main() {
+    foo(|| panic!());
+}
diff --git a/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr b/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
new file mode 100644 (file)
index 0000000..78d1a3c
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0271]: type mismatch resolving `<[closure@$DIR/fallback-closure-wrap.rs:18:40: 21:6] as FnOnce<()>>::Output == ()`
+  --> $DIR/fallback-closure-wrap.rs:18:31
+   |
+LL |       let error = Closure::wrap(Box::new(move || {
+   |  _______________________________^
+LL | |
+LL | |         panic!("Can't connect to server.");
+LL | |     }) as Box<dyn FnMut()>);
+   | |______^ expected `()`, found `!`
+   |
+   = note: expected unit type `()`
+                   found type `!`
+   = note: required for the cast to the object type `dyn FnMut()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/never_type/fallback-closure-wrap.rs b/src/test/ui/never_type/fallback-closure-wrap.rs
new file mode 100644 (file)
index 0000000..af0577a
--- /dev/null
@@ -0,0 +1,30 @@
+// This is a minified example from Crater breakage observed when attempting to
+// stabilize never type, nstoddard/webgl-gui @ 22f0169f.
+//
+// This particular test case currently fails as the inference to `()` rather
+// than `!` happens as a result of an `as` cast, which is not currently tracked.
+// Crater did not find many cases of this occuring, but it is included for
+// awareness.
+//
+// revisions: nofallback fallback
+//[nofallback] check-pass
+//[fallback] check-fail
+
+#![cfg_attr(fallback, feature(never_type_fallback))]
+
+use std::marker::PhantomData;
+
+fn main() {
+    let error = Closure::wrap(Box::new(move || {
+        //[fallback]~^ ERROR type mismatch resolving
+        panic!("Can't connect to server.");
+    }) as Box<dyn FnMut()>);
+}
+
+struct Closure<T: ?Sized>(PhantomData<T>);
+
+impl<T: ?Sized> Closure<T> {
+    fn wrap(data: Box<T>) -> Closure<T> {
+        todo!()
+    }
+}
diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
new file mode 100644 (file)
index 0000000..f374266
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `E: From<()>` is not satisfied
+  --> $DIR/never-value-fallback-issue-66757.rs:27:5
+   |
+LL |     <E as From<_>>::from(never);
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E`
+   |
+   = help: the following implementations were found:
+             <E as From<!>>
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
index f2e9e087307db833f47d04fd57ec0a0728055040..6dc7e6ad2d93de43f267af45bfa69836d55cfbe4 100644 (file)
@@ -4,12 +4,13 @@
 // never) and an uninferred variable (here the argument to `From`) it
 // doesn't fallback to `()` but rather `!`.
 //
-// run-pass
+// revisions: nofallback fallback
+//[fallback] run-pass
+//[nofallback] check-fail
 
 #![feature(never_type)]
 
-// FIXME(#67225) -- this should be true even without the fallback gate.
-#![feature(never_type_fallback)]
+#![cfg_attr(fallback, feature(never_type_fallback))]
 
 struct E;
 
@@ -23,7 +24,7 @@ fn from(_: !) -> E {
 #[allow(dead_code)]
 fn foo(never: !) {
     <E as From<!>>::from(never);  // Ok
-    <E as From<_>>::from(never);  // Inference fails here
+    <E as From<_>>::from(never);  //[nofallback]~ ERROR trait bound `E: From<()>` is not satisfied
 }
 
 fn main() { }
index 418cf554b49be7f75d09622fd4985ede64b801ae..c56e1dd46254ff59ee64d0bf94fbb67f0e8134e1 100644 (file)
@@ -5,7 +5,6 @@
  * 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.
 
@@ -17,12 +16,12 @@ struct Structure {
 }
 
 pub fn main() {
-    let y: Box<isize> = box 2;
-    let b: Box<isize> = box (1 + 2);
-    let c = box (3 + 4);
+    let y: Box<isize> = Box::new(2);
+    let b: Box<isize> = Box::new(1 + 2);
+    let c = Box::new(3 + 4);
 
-    let s: Box<Structure> = box Structure {
+    let s: Box<Structure> = Box::new(Structure {
         x: 3,
         y: 4,
-    };
+    });
 }
index d11f0d045a7e422e7b874613d4dfd3a05354c0c2..96a3b197f461cf59a76fc9869e89cecd4a275e6d 100644 (file)
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(box_syntax)]
-
 fn f(x: Box<isize>) {
     let y: &isize = &*x;
     println!("{}", *x);
@@ -27,6 +25,6 @@ fn g(x: Box<dyn Trait>) {
 }
 
 fn main() {
-    f(box 1234);
-    g(box Struct as Box<dyn Trait>);
+    f(Box::new(1234));
+    g(Box::new(Struct) as Box<dyn Trait>);
 }
index a7be365bde4bdf78c9c4da1d8b0d9a45b25e4454..f6bbb2d14b003afb80e9f1d0225663f9bbe1be9a 100644 (file)
@@ -1,16 +1,16 @@
-#![feature(box_syntax)]
-
 trait Foo { fn get(&self); }
 
 impl<A> Foo for A {
     fn get(&self) { }
 }
 
+
+
 fn main() {
     let _ = {
         let tmp0 = 3;
         let tmp1 = &tmp0;
-        box tmp1 as Box<dyn Foo + '_>
+        Box::new(tmp1) as Box<dyn Foo + '_>
     };
     //~^^^ ERROR `tmp0` does not live long enough
 }
index b71893de7f8bdca925bcf391dac445e1908dd97a..5cedea6e66520a5e022ce895232324b31bb79272 100644 (file)
@@ -3,8 +3,8 @@ error[E0597]: `tmp0` does not live long enough
    |
 LL |         let tmp1 = &tmp0;
    |                    ^^^^^ borrowed value does not live long enough
-LL |         box tmp1 as Box<dyn Foo + '_>
-   |         ----------------------------- borrow later captured here by trait object
+LL |         Box::new(tmp1) as Box<dyn Foo + '_>
+   |         ----------------------------------- borrow later captured here by trait object
 LL |     };
    |     - `tmp0` dropped here while still borrowed
 
index f34df4e2dd143f66758a82124e847f2bc6f3623c..93da7c3e0ddd65ca368fa9a4c65cd88ffaff5bca 100644 (file)
@@ -2,7 +2,7 @@ error: malformed `crate_type` attribute input
   --> $DIR/no_crate_type.rs:2:1
    |
 LL | #![crate_type]
-   | ^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
+   | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
index 568c3e144be2c302cabef8446cd0f166954bad0a..f9edba6743499dddcfe13e4ea0e8b5095cf3a2bf 100644 (file)
@@ -1,7 +1,5 @@
 // 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".  -- https://coq.inria.fr/doc/language/core/conversion.html#iota-reduction
@@ -64,7 +62,7 @@ macro_rules! check_type {
 
 pub fn main() {
     check_type!(&17, &isize);
-    check_type!(box 18, Box<isize>);
+    check_type!(Box::new(18), Box<isize>);
     check_type!("foo".to_string(), String);
     check_type!(vec![20, 22], Vec<isize>);
     check_type!(main, fn(), |pthing| {
index 9b88d8ea7bcd9444b5a5ecfffe2f26d00f9a6c3f..fce1341fc74154c7105cdd86407232660fef973b 100644 (file)
@@ -3,9 +3,6 @@
 // closed over do not contain managed values, and thus the boxes do
 // not have headers.
 
-#![feature(box_syntax)]
-
-
 trait FooTrait {
     fn foo(&self) -> usize;
 }
@@ -22,9 +19,9 @@ fn foo(&self) -> usize {
 
 pub fn main() {
     let foos: Vec<Box<dyn FooTrait>> = vec![
-        box BarStruct{ x: 0 } as Box<dyn FooTrait>,
-        box BarStruct{ x: 1 } as Box<dyn FooTrait>,
-        box BarStruct{ x: 2 } as Box<dyn FooTrait>
+        Box::new(BarStruct{ x: 0 }) as Box<dyn FooTrait>,
+        Box::new(BarStruct{ x: 1 }) as Box<dyn FooTrait>,
+        Box::new(BarStruct{ x: 2 }) as Box<dyn FooTrait>,
     ];
 
     for i in 0..foos.len() {
index 4b7b68f22176f6576f3f5097dabe5baa80364c74..15677a5185c2f1a2776c3f84b6be7b9d496189de 100644 (file)
@@ -3,8 +3,6 @@
 // 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<Self>) -> usize;
 }
@@ -20,6 +18,6 @@ fn foo(self: Box<BarStruct>) -> usize {
 }
 
 pub fn main() {
-    let foo = box BarStruct{ x: 22 } as Box<dyn FooTrait>;
+    let foo = Box::new(BarStruct{ x: 22 }) as Box<dyn FooTrait>;
     assert_eq!(22, foo.foo());
 }
index 213fd2619cee7d9979d460215f734c23a95fc51e..f36682a3dd82132b577ccfece5b28e9e7147c694 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
 fn main() {
+
     let f;
     let g;
+
     g = f;
-    f = box g;
+    f = Box::new(g);
     //~^  ERROR mismatched types
     //~| cyclic type of infinite size
 }
index c004043307899f11a6e7e6bde1bbd5b2ea4cf3ec..dcbfc81b4d51928f25c43cf3f06c4dd1434002fc 100644 (file)
@@ -1,13 +1,10 @@
 error[E0308]: mismatched types
   --> $DIR/occurs-check-2.rs:7:9
    |
-LL |     f = box g;
-   |         ^^^^^ cyclic type of infinite size
-   |
-help: try using a conversion method
-   |
-LL |     f = (box g).to_string();
-   |         +     +++++++++++++
+LL |     f = Box::new(g);
+   |         ^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
+   |         |
+   |         cyclic type of infinite size
 
 error: aborting due to previous error
 
index 5f2c2362d24cd81c9230d47ae274eff901133b9d..aec52d839766ad3e42ec040a30a6cf4e0572bae7 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn main() {
+
     let f;
-    f = box f;
+
+    f = Box::new(f);
     //~^ ERROR mismatched types
     //~| cyclic type of infinite size
 }
index 452163e2fa5ee44fd9a0b71c66e32244373707fe..3e1ef2e719ad570a6d2f497a8293873cbc7f050a 100644 (file)
@@ -1,13 +1,10 @@
 error[E0308]: mismatched types
   --> $DIR/occurs-check.rs:5:9
    |
-LL |     f = box f;
-   |         ^^^^^ cyclic type of infinite size
-   |
-help: try using a conversion method
-   |
-LL |     f = (box f).to_string();
-   |         +     +++++++++++++
+LL |     f = Box::new(f);
+   |         ^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
+   |         |
+   |         cyclic type of infinite size
 
 error: aborting due to previous error
 
index af4caf75669967d0b8cda24859f4e1560be69e53..7c20a2b2f94e8d3fc223c5bb2ef15fa841da5f9a 100644 (file)
@@ -7,22 +7,21 @@
 
 #![allow(dead_assignment)]
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 
 struct A { a: isize, b: isize }
 struct Abox { a: Box<isize>, b: Box<isize> }
 
 fn ret_int_i() -> isize { 10 }
 
-fn ret_ext_i() -> Box<isize> { box 10 }
+fn ret_ext_i() -> Box<isize> { Box::new(10) }
 
 fn ret_int_rec() -> A { A {a: 10, b: 10} }
 
-fn ret_ext_rec() -> Box<A> { box A {a: 10, b: 10} }
+fn ret_ext_rec() -> Box<A> { Box::new(A {a: 10, b: 10}) }
 
-fn ret_ext_mem() -> Abox { Abox {a: box 10, b: box 10} }
+fn ret_ext_mem() -> Abox { Abox {a: Box::new(10), b: Box::new(10) } }
 
-fn ret_ext_ext_mem() -> Box<Abox> { box Abox{a: box 10, b: box 10} }
+fn ret_ext_ext_mem() -> Box<Abox> { Box::new(Abox{a: Box::new(10), b: Box::new(10) }) }
 
 pub fn main() {
     let mut int_i: isize;
index e850633e34fee1e674c04fda455181ed2ee81fda..cae3ec906211e86b60cf0b4a3d1cafb1f2ff4ccb 100644 (file)
@@ -2,8 +2,6 @@
 #![allow(unused_variables)]
 #![allow(stable_features)]
 
-#![feature(box_syntax, core)]
-
 use std::cell::RefCell;
 use std::rc::Rc;
 
@@ -14,7 +12,7 @@ struct Point {
 }
 
 pub fn main() {
-    let box_5: Box<_> = box 5_usize;
+    let box_5: Box<_> = Box::new(5_usize);
     let point = Rc::new(Point {x: 2, y: 4});
     assert_eq!(point.x, 2);
     assert_eq!(point.y, 4);
index 6996ee32933c088ac8581b6e6d5e86932e2ff60b..41f9efa8c1619348d4203c63645756b696b79617 100644 (file)
@@ -3,8 +3,6 @@
 
 // Test overloaded indexing combined with autoderef.
 
-#![feature(box_syntax, core)]
-
 use std::ops::{Index, IndexMut};
 
 struct Foo {
@@ -47,10 +45,10 @@ fn get_from_ref(&self) -> isize { *self }
 }
 
 fn main() {
-    let mut f: Box<_> = box Foo {
+    let mut f: Box<_> = Box::new(Foo {
         x: 1,
         y: 2,
-    };
+    });
 
     assert_eq!(f[1], 2);
 
index 322054caf116140b92e2b4d54a8be8e103f522d9..7636025c25b8324c5c7345c760590fef141aff2f 100644 (file)
@@ -2,12 +2,10 @@
 // error-pattern:meep
 // ignore-emscripten no processes
 
-#![feature(box_syntax)]
-
 fn f(_a: isize, _b: isize, _c: Box<isize>) {
     panic!("moop");
 }
 
 fn main() {
-    f(1, panic!("meep"), box 42);
+    f(1, panic!("meep"), Box::new(42));
 }
index 08acc6e8078f9b8df2b804ee4a30e019f34f186f..c7df5365474e950970670ed9230f716ec5dba435 100644 (file)
@@ -2,9 +2,8 @@
 // error-pattern:panicked at 'Box<dyn Any>'
 // ignore-emscripten no processes
 
-#![feature(box_syntax)]
 #![allow(non_fmt_panics)]
 
 fn main() {
-    panic!(box 413 as Box<dyn std::any::Any + Send>);
+    panic!(Box::new(413) as Box<dyn std::any::Any + Send>);
 }
index 862026408ef7f8d9db8a9631a37f9b2f98c70f4e..a37a806a15749e449cf26e99dc64ee9f56c8dad2 100644 (file)
@@ -26,7 +26,7 @@ LL |         bar {  }
 help: if `bar` is a function, use the arguments directly
    |
 LL -         bar(baz: $rest)
-LL +         bar(true);
+LL +         bar(: $rest)
    | 
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/parser/issue-88770.rs b/src/test/ui/parser/issue-88770.rs
new file mode 100644 (file)
index 0000000..bf89033
--- /dev/null
@@ -0,0 +1,11 @@
+// Regression test for the ICE described in #88770.
+
+// error-pattern:this file contains an unclosed delimiter
+// error-pattern:expected one of
+// error-pattern:missing `in` in `for` loop
+// error-pattern:expected `;`, found `e`
+
+fn m(){print!("",(c for&g
+u
+e
+e
diff --git a/src/test/ui/parser/issue-88770.stderr b/src/test/ui/parser/issue-88770.stderr
new file mode 100644 (file)
index 0000000..c7e2415
--- /dev/null
@@ -0,0 +1,66 @@
+error: this file contains an unclosed delimiter
+  --> $DIR/issue-88770.rs:11:3
+   |
+LL | fn m(){print!("",(c for&g
+   |       -      -   - unclosed delimiter
+   |       |      |
+   |       |      unclosed delimiter
+   |       unclosed delimiter
+...
+LL | e
+   |   ^
+
+error: this file contains an unclosed delimiter
+  --> $DIR/issue-88770.rs:11:3
+   |
+LL | fn m(){print!("",(c for&g
+   |       -      -   - unclosed delimiter
+   |       |      |
+   |       |      unclosed delimiter
+   |       unclosed delimiter
+...
+LL | e
+   |   ^
+
+error: this file contains an unclosed delimiter
+  --> $DIR/issue-88770.rs:11:3
+   |
+LL | fn m(){print!("",(c for&g
+   |       -      -   - unclosed delimiter
+   |       |      |
+   |       |      unclosed delimiter
+   |       unclosed delimiter
+...
+LL | e
+   |   ^
+
+error: missing `in` in `for` loop
+  --> $DIR/issue-88770.rs:8:26
+   |
+LL |   fn m(){print!("",(c for&g
+   |  __________________________^
+LL | | u
+   | |_ help: try adding `in` here
+
+error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found keyword `for`
+  --> $DIR/issue-88770.rs:8:21
+   |
+LL | fn m(){print!("",(c for&g
+   |                     ^^^ expected one of 8 possible tokens
+
+error: expected `;`, found `e`
+  --> $DIR/issue-88770.rs:10:2
+   |
+LL | e
+   |  ^ help: add `;` here
+LL | e
+   | - unexpected token
+
+error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `)`
+  --> $DIR/issue-88770.rs:11:3
+   |
+LL | e
+   |   ^ expected one of 7 possible tokens
+
+error: aborting due to 7 previous errors
+
index 33c30d731087795996a48735fd23b3dfcb18c113..61819cabdf178514905a96e47a0525a298835d83 100644 (file)
@@ -1,10 +1,9 @@
 // build-pass (FIXME(62277): could be check-pass?)
 
-#![feature(box_syntax)]
 #![allow(bare_trait_objects)]
 
 use std::fmt::Debug;
 
 fn main() {
-    let x: Box<Debug+> = box 3 as Box<Debug+>; // Trailing `+` is OK
+    let x: Box<Debug+> = Box::new(3) as Box<Debug+>; // Trailing `+` is OK
 }
diff --git a/src/test/ui/parser/unicode-character-literal.fixed b/src/test/ui/parser/unicode-character-literal.fixed
new file mode 100644 (file)
index 0000000..26ef5ff
--- /dev/null
@@ -0,0 +1,21 @@
+// Regression test for #88684: Improve diagnostics for combining marks
+// in character literals.
+
+// run-rustfix
+
+fn main() {
+    let _spade = "♠️";
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}`
+    //~| HELP: if you meant to write a `str` literal, use double quotes
+
+    let _s = "ṩ̂̊";
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+    //~| HELP: if you meant to write a `str` literal, use double quotes
+
+    let _a = 'Å';
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `A` is followed by the combining mark `\u{30a}`
+    //~| HELP: consider using the normalized form `\u{c5}` of this character
+}
diff --git a/src/test/ui/parser/unicode-character-literal.rs b/src/test/ui/parser/unicode-character-literal.rs
new file mode 100644 (file)
index 0000000..d331522
--- /dev/null
@@ -0,0 +1,21 @@
+// Regression test for #88684: Improve diagnostics for combining marks
+// in character literals.
+
+// run-rustfix
+
+fn main() {
+    let _spade = '♠️';
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}`
+    //~| HELP: if you meant to write a `str` literal, use double quotes
+
+    let _s = 'ṩ̂̊';
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+    //~| HELP: if you meant to write a `str` literal, use double quotes
+
+    let _a = 'Å';
+    //~^ ERROR: character literal may only contain one codepoint
+    //~| NOTE: this `A` is followed by the combining mark `\u{30a}`
+    //~| HELP: consider using the normalized form `\u{c5}` of this character
+}
diff --git a/src/test/ui/parser/unicode-character-literal.stderr b/src/test/ui/parser/unicode-character-literal.stderr
new file mode 100644 (file)
index 0000000..5cd3bd0
--- /dev/null
@@ -0,0 +1,48 @@
+error: character literal may only contain one codepoint
+  --> $DIR/unicode-character-literal.rs:7:18
+   |
+LL |     let _spade = '♠️';
+   |                  ^^^
+   |
+note: this `♠` is followed by the combining mark `\u{fe0f}`
+  --> $DIR/unicode-character-literal.rs:7:19
+   |
+LL |     let _spade = '♠️';
+   |                   ^
+help: if you meant to write a `str` literal, use double quotes
+   |
+LL |     let _spade = "♠️";
+   |                  ~~~
+
+error: character literal may only contain one codepoint
+  --> $DIR/unicode-character-literal.rs:12:14
+   |
+LL |     let _s = 'ṩ̂̊';
+   |              ^^^
+   |
+note: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+  --> $DIR/unicode-character-literal.rs:12:15
+   |
+LL |     let _s = 'ṩ̂̊';
+   |               ^
+help: if you meant to write a `str` literal, use double quotes
+   |
+LL |     let _s = "ṩ̂̊";
+   |              ~~~
+
+error: character literal may only contain one codepoint
+  --> $DIR/unicode-character-literal.rs:17:14
+   |
+LL |     let _a = 'Å';
+   |              ^-^
+   |               |
+   |               help: consider using the normalized form `\u{c5}` of this character: `Å`
+   |
+note: this `A` is followed by the combining mark `\u{30a}`
+  --> $DIR/unicode-character-literal.rs:17:15
+   |
+LL |     let _a = 'Å';
+   |               ^
+
+error: aborting due to 3 previous errors
+
index 8b391cd95d7f78c1fb4d348a6d71a119e6ae7b14..3cb92a54029dc03cdea9190fd3762f139f767f25 100644 (file)
@@ -1,9 +1,9 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 #![allow(dead_code)]
 #![allow(unused_variables)]
 #![deny(unreachable_patterns)]
 
+
 enum IntList {
     Cons(isize, Box<IntList>),
     Nil
@@ -12,9 +12,9 @@ enum IntList {
 fn tail(source_list: &IntList) -> IntList {
     match source_list {
         &IntList::Cons(val, box ref next_list) => tail(next_list),
-        &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, box IntList::Nil),
-//~^ ERROR unreachable pattern
-        _                          => panic!()
+        &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, Box::new(IntList::Nil)),
+        //~^ ERROR unreachable pattern
+        _ => panic!(),
     }
 }
 
index 4d162eb77e725879e71ea638d717474ee730f0c3..7f15c4703a31c2238ef4a9da649bc6411b75ff09 100644 (file)
@@ -1,11 +1,11 @@
 error: unreachable pattern
   --> $DIR/issue-12116.rs:15:9
    |
-LL |         &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, box IntList::Nil),
+LL |         &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, Box::new(IntList::Nil)),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-12116.rs:5:9
+  --> $DIR/issue-12116.rs:4:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
index e33359beccdefb5d437d6e8894b9696968676163..6215a23980d6d32a75f5f362b738bb039a3a51de 100644 (file)
@@ -1,5 +1,4 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 struct HTMLImageData {
     image: Option<String>
@@ -23,8 +22,9 @@ struct NodeData {
 
 fn main() {
     let mut id = HTMLImageData { image: None };
-    let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) };
-    let n = NodeData {kind : box NodeKind::Element(ed)};
+    let ed = ElementData { kind: Box::new(ElementKind::HTMLImageElement(id)) };
+    let n = NodeData { kind: Box::new(NodeKind::Element(ed)) };
+
     // n.b. span could be better
     match n.kind {
         box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
diff --git a/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs b/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs
deleted file mode 100644 (file)
index f0fec67..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// gate-test-macro_attributes_in_derive_output
-// aux-build: test-macros.rs
-
-#![feature(proc_macro_hygiene)]
-#![feature(stmt_expr_attributes)]
-
-#[macro_use]
-extern crate test_macros;
-
-#[derive(Empty)]
-#[empty_attr] //~ ERROR macro attributes in `#[derive]` output are unstable
-struct S1 {
-    field: [u8; 10],
-}
-
-#[derive(Empty)]
-#[empty_helper]
-#[empty_attr] //~ ERROR macro attributes in `#[derive]` output are unstable
-struct S2 {
-    field: [u8; 10],
-}
-
-#[derive(Empty)]
-struct S3 {
-    field: [u8; #[identity_attr] 10], //~ ERROR macro attributes in `#[derive]` output are unstable
-}
-
-#[derive(Empty)]
-struct S4 {
-    field: [u8; {
-        #[derive(Empty)] // OK, not gated
-        struct Inner;
-        10
-    }]
-}
-
-fn main() {}
diff --git a/src/test/ui/proc-macro/attribute-after-derive-feature-gate.stderr b/src/test/ui/proc-macro/attribute-after-derive-feature-gate.stderr
deleted file mode 100644 (file)
index 74cace6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-error[E0658]: macro attributes in `#[derive]` output are unstable
-  --> $DIR/attribute-after-derive-feature-gate.rs:11:3
-   |
-LL | #[empty_attr]
-   |   ^^^^^^^^^^
-   |
-   = note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
-   = help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
-
-error[E0658]: macro attributes in `#[derive]` output are unstable
-  --> $DIR/attribute-after-derive-feature-gate.rs:18:3
-   |
-LL | #[empty_attr]
-   |   ^^^^^^^^^^
-   |
-   = note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
-   = help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
-
-error[E0658]: macro attributes in `#[derive]` output are unstable
-  --> $DIR/attribute-after-derive-feature-gate.rs:25:19
-   |
-LL |     field: [u8; #[identity_attr] 10],
-   |                   ^^^^^^^^^^^^^
-   |
-   = note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
-   = help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index ac3f28b6ef3ea119e50cfce971341cf175e6399a..0f0f27bff97be8b89ac4e7841950a6837c709e75 100644 (file)
@@ -5,8 +5,6 @@
 // compile-flags: -Z span-debug
 // aux-build: test-macros.rs
 
-#![feature(macro_attributes_in_derive_output)]
-
 #![no_std] // Don't load unnecessary hygiene information from std
 extern crate std;
 
index 4c48e41ff338b38c62b93a9fb5660c20a97e90a9..c5b84b0367c8fbdf1c5c501a2811a574e1a54988 100644 (file)
@@ -3,35 +3,35 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
         spacing: Alone,
-        span: $DIR/attribute-after-derive.rs:17:1: 17:2 (#0),
+        span: $DIR/attribute-after-derive.rs:15:1: 15:2 (#0),
     },
     Group {
         delimiter: Bracket,
         stream: TokenStream [
             Ident {
                 ident: "derive",
-                span: $DIR/attribute-after-derive.rs:17:3: 17:9 (#0),
+                span: $DIR/attribute-after-derive.rs:15:3: 15:9 (#0),
             },
             Group {
                 delimiter: Parenthesis,
                 stream: TokenStream [
                     Ident {
                         ident: "Print",
-                        span: $DIR/attribute-after-derive.rs:17:10: 17:15 (#0),
+                        span: $DIR/attribute-after-derive.rs:15:10: 15:15 (#0),
                     },
                 ],
-                span: $DIR/attribute-after-derive.rs:17:9: 17:16 (#0),
+                span: $DIR/attribute-after-derive.rs:15:9: 15:16 (#0),
             },
         ],
-        span: $DIR/attribute-after-derive.rs:17:2: 17:17 (#0),
+        span: $DIR/attribute-after-derive.rs:15:2: 15:17 (#0),
     },
     Ident {
         ident: "struct",
-        span: $DIR/attribute-after-derive.rs:18:1: 18:7 (#0),
+        span: $DIR/attribute-after-derive.rs:16:1: 16:7 (#0),
     },
     Ident {
         ident: "AttributeDerive",
-        span: $DIR/attribute-after-derive.rs:18:8: 18:23 (#0),
+        span: $DIR/attribute-after-derive.rs:16:8: 16:23 (#0),
     },
     Group {
         delimiter: Brace,
@@ -39,64 +39,64 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
             Punct {
                 ch: '#',
                 spacing: Alone,
-                span: $DIR/attribute-after-derive.rs:19:5: 19:6 (#0),
+                span: $DIR/attribute-after-derive.rs:17:5: 17:6 (#0),
             },
             Group {
                 delimiter: Bracket,
                 stream: TokenStream [
                     Ident {
                         ident: "cfg",
-                        span: $DIR/attribute-after-derive.rs:19:7: 19:10 (#0),
+                        span: $DIR/attribute-after-derive.rs:17:7: 17:10 (#0),
                     },
                     Group {
                         delimiter: Parenthesis,
                         stream: TokenStream [
                             Ident {
                                 ident: "FALSE",
-                                span: $DIR/attribute-after-derive.rs:19:11: 19:16 (#0),
+                                span: $DIR/attribute-after-derive.rs:17:11: 17:16 (#0),
                             },
                         ],
-                        span: $DIR/attribute-after-derive.rs:19:10: 19:17 (#0),
+                        span: $DIR/attribute-after-derive.rs:17:10: 17:17 (#0),
                     },
                 ],
-                span: $DIR/attribute-after-derive.rs:19:6: 19:18 (#0),
+                span: $DIR/attribute-after-derive.rs:17:6: 17:18 (#0),
             },
             Ident {
                 ident: "field",
-                span: $DIR/attribute-after-derive.rs:20:5: 20:10 (#0),
+                span: $DIR/attribute-after-derive.rs:18:5: 18:10 (#0),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/attribute-after-derive.rs:20:10: 20:11 (#0),
+                span: $DIR/attribute-after-derive.rs:18:10: 18:11 (#0),
             },
             Ident {
                 ident: "u8",
-                span: $DIR/attribute-after-derive.rs:20:12: 20:14 (#0),
+                span: $DIR/attribute-after-derive.rs:18:12: 18:14 (#0),
             },
             Punct {
                 ch: ',',
                 spacing: Alone,
-                span: $DIR/attribute-after-derive.rs:20:14: 20:15 (#0),
+                span: $DIR/attribute-after-derive.rs:18:14: 18:15 (#0),
             },
         ],
-        span: $DIR/attribute-after-derive.rs:18:24: 21:2 (#0),
+        span: $DIR/attribute-after-derive.rs:16:24: 19:2 (#0),
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): struct AttributeDerive { }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: $DIR/attribute-after-derive.rs:18:1: 18:7 (#0),
+        span: $DIR/attribute-after-derive.rs:16:1: 16:7 (#0),
     },
     Ident {
         ident: "AttributeDerive",
-        span: $DIR/attribute-after-derive.rs:18:8: 18:23 (#0),
+        span: $DIR/attribute-after-derive.rs:16:8: 16:23 (#0),
     },
     Group {
         delimiter: Brace,
         stream: TokenStream [],
-        span: $DIR/attribute-after-derive.rs:18:24: 21:2 (#0),
+        span: $DIR/attribute-after-derive.rs:16:24: 19:2 (#0),
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): #[print_attr] struct DeriveAttribute { }
@@ -104,45 +104,89 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
         spacing: Alone,
-        span: $DIR/attribute-after-derive.rs:24:1: 24:2 (#0),
+        span: $DIR/attribute-after-derive.rs:22:1: 22:2 (#0),
     },
     Group {
         delimiter: Bracket,
         stream: TokenStream [
             Ident {
                 ident: "print_attr",
-                span: $DIR/attribute-after-derive.rs:24:3: 24:13 (#0),
+                span: $DIR/attribute-after-derive.rs:22:3: 22:13 (#0),
             },
         ],
-        span: $DIR/attribute-after-derive.rs:24:2: 24:14 (#0),
+        span: $DIR/attribute-after-derive.rs:22:2: 22:14 (#0),
     },
     Ident {
         ident: "struct",
-        span: $DIR/attribute-after-derive.rs:25:1: 25:7 (#0),
+        span: $DIR/attribute-after-derive.rs:23:1: 23:7 (#0),
     },
     Ident {
         ident: "DeriveAttribute",
-        span: $DIR/attribute-after-derive.rs:25:8: 25:23 (#0),
+        span: $DIR/attribute-after-derive.rs:23:8: 23:23 (#0),
     },
     Group {
         delimiter: Brace,
         stream: TokenStream [],
-        span: $DIR/attribute-after-derive.rs:25:24: 28:2 (#0),
+        span: $DIR/attribute-after-derive.rs:23:24: 26:2 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
+PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { #[cfg(FALSE)] field : u8, }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: $DIR/attribute-after-derive.rs:25:1: 25:7 (#0),
+        span: $DIR/attribute-after-derive.rs:23:1: 23:7 (#0),
     },
     Ident {
         ident: "DeriveAttribute",
-        span: $DIR/attribute-after-derive.rs:25:8: 25:23 (#0),
+        span: $DIR/attribute-after-derive.rs:23:8: 23:23 (#0),
     },
     Group {
         delimiter: Brace,
-        stream: TokenStream [],
-        span: $DIR/attribute-after-derive.rs:25:24: 28:2 (#0),
+        stream: TokenStream [
+            Punct {
+                ch: '#',
+                spacing: Alone,
+                span: $DIR/attribute-after-derive.rs:24:5: 24:6 (#0),
+            },
+            Group {
+                delimiter: Bracket,
+                stream: TokenStream [
+                    Ident {
+                        ident: "cfg",
+                        span: $DIR/attribute-after-derive.rs:24:7: 24:10 (#0),
+                    },
+                    Group {
+                        delimiter: Parenthesis,
+                        stream: TokenStream [
+                            Ident {
+                                ident: "FALSE",
+                                span: $DIR/attribute-after-derive.rs:24:11: 24:16 (#0),
+                            },
+                        ],
+                        span: $DIR/attribute-after-derive.rs:24:10: 24:17 (#0),
+                    },
+                ],
+                span: $DIR/attribute-after-derive.rs:24:6: 24:18 (#0),
+            },
+            Ident {
+                ident: "field",
+                span: $DIR/attribute-after-derive.rs:25:5: 25:10 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/attribute-after-derive.rs:25:10: 25:11 (#0),
+            },
+            Ident {
+                ident: "u8",
+                span: $DIR/attribute-after-derive.rs:25:12: 25:14 (#0),
+            },
+            Punct {
+                ch: ',',
+                spacing: Alone,
+                span: $DIR/attribute-after-derive.rs:25:14: 25:15 (#0),
+            },
+        ],
+        span: $DIR/attribute-after-derive.rs:23:24: 26:2 (#0),
     },
 ]
index 2ff6f935a03c15c11554801aadf9deb37a9550db..2f2ece75ebeeb0c7cead9f59b4e96559cbc7a045 100644 (file)
@@ -5,8 +5,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 fn sums_to(v: Vec<isize> , sum: isize) -> bool {
     let mut i = 0;
     let mut sum0 = 0;
@@ -19,7 +17,7 @@ fn sums_to(v: Vec<isize> , sum: isize) -> bool {
 
 fn sums_to_using_uniq(v: Vec<isize> , sum: isize) -> bool {
     let mut i = 0;
-    let mut sum0: Box<_> = box 0;
+    let mut sum0: Box<_> = 0.into();
     while i < v.len() {
         *sum0 += v[i];
         i += 1;
@@ -41,7 +39,7 @@ struct F<T> { f: T }
 
 fn sums_to_using_uniq_rec(v: Vec<isize> , sum: isize) -> bool {
     let mut i = 0;
-    let mut sum0 = F::<Box<_>> {f: box 0};
+    let mut sum0 = F::<Box<_>> {f: 0.into() };
     while i < v.len() {
         *sum0.f += v[i];
         i += 1;
index 37113bc0a050bf95393e0edcba22f3e56a3a761e..7f32b8b91a6f0c6a7f20295ffe65f99c6fd6c9ab 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
 
 #![allow(non_camel_case_types)]
-#![feature(box_syntax)]
 
 trait get {
     fn get(self) -> isize;
@@ -17,7 +16,7 @@ fn get(self) -> isize {
 }
 
 pub fn main() {
-    let x: Box<_> = box 6;
+    let x: Box<_> = 6.into();
     let y = x.get();
     println!("y={}", y);
     assert_eq!(y, 6);
index 243fed0c8ce528bad27edd4df0883ac44830c3a2..6049321337c75379051186e3889edf3f87d16b4d 100644 (file)
@@ -1,5 +1,5 @@
-#![feature(box_syntax)]
 #![allow(unused_variables)]
+
 #![deny(unreachable_code)]
 
 fn main() {
index 64c3896851669fc52f65503267f7d4d5794b70f0..3277bf0d52b201babb349bb9e39c6548ae8478e3 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
+
 #![allow(dead_code)]
 #![deny(unreachable_patterns)]
 
index 03cb3e24b7dbff0c49ca7c063aa2370779e8deda..4fd5622b0626ce8949770710dd9b0f2d2ad3e47d 100644 (file)
@@ -1,8 +1,8 @@
 //~ ERROR cycle detected when computing layout of `S`
-//~| NOTE ...which requires computing layout of `std::option::Option<<S as Mirror>::It>`...
-//~| NOTE ...which requires computing layout of `std::option::Option<S>`...
+//~| NOTE ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
+//~| NOTE ...which requires computing layout of `core::option::Option<S>`...
 //~| NOTE ...which again requires computing layout of `S`, completing the cycle
-//~| NOTE cycle used when computing layout of `std::option::Option<S>`
+//~| NOTE cycle used when computing layout of `core::option::Option<S>`
 
 // build-fail
 
index 21c0e1e6de5f34b05f0704995dbda5d3e1d6ce88..6042379a91887c4bbe2bd5239f0fd1f685a531a4 100644 (file)
@@ -1,9 +1,9 @@
 error[E0391]: cycle detected when computing layout of `S`
    |
-   = note: ...which requires computing layout of `std::option::Option<<S as Mirror>::It>`...
-   = note: ...which requires computing layout of `std::option::Option<S>`...
+   = note: ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
+   = note: ...which requires computing layout of `core::option::Option<S>`...
    = note: ...which again requires computing layout of `S`, completing the cycle
-   = note: cycle used when computing layout of `std::option::Option<S>`
+   = note: cycle used when computing layout of `core::option::Option<S>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion_limit/invalid_digit_type.rs b/src/test/ui/recursion_limit/invalid_digit_type.rs
new file mode 100644 (file)
index 0000000..e408109
--- /dev/null
@@ -0,0 +1,3 @@
+#![recursion_limit = 123] //~ ERROR malformed `recursion_limit` attribute
+
+fn main() {}
diff --git a/src/test/ui/recursion_limit/invalid_digit_type.stderr b/src/test/ui/recursion_limit/invalid_digit_type.stderr
new file mode 100644 (file)
index 0000000..6d1409b
--- /dev/null
@@ -0,0 +1,8 @@
+error: malformed `recursion_limit` attribute input
+  --> $DIR/invalid_digit_type.rs:1:1
+   |
+LL | #![recursion_limit = 123]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/recursion_limit/invalid_macro.rs b/src/test/ui/recursion_limit/invalid_macro.rs
new file mode 100644 (file)
index 0000000..7db67a8
--- /dev/null
@@ -0,0 +1,7 @@
+#![recursion_limit = foo!()] //~ ERROR malformed `recursion_limit` attribute
+
+macro_rules! foo {
+    () => {"128"};
+}
+
+fn main() {}
diff --git a/src/test/ui/recursion_limit/invalid_macro.stderr b/src/test/ui/recursion_limit/invalid_macro.stderr
new file mode 100644 (file)
index 0000000..0189e99
--- /dev/null
@@ -0,0 +1,8 @@
+error: malformed `recursion_limit` attribute input
+  --> $DIR/invalid_macro.rs:1:1
+   |
+LL | #![recursion_limit = foo!()]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]`
+
+error: aborting due to previous error
+
index 0ade359923a0e6c6449d8d4385e61f1c7ccb1186..d8f2abb0c3c217039f9aed0cae44081f6ae9cfd8 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax)]
-
 trait X {
     fn get_i(&self) -> isize;
 }
 
 
+
+
 struct B {
     i: isize
 }
@@ -24,7 +24,7 @@ fn make_a<'a>(p: &'a dyn X) -> A<'a> {
 }
 
 fn make_make_a<'a>() -> A<'a> {
-    let b: Box<B> = box B {i:1};
+    let b: Box<B> = Box::new(B { i: 1 });
     let bb: &B = &*b;
     make_a(bb)  //~ ERROR cannot return value referencing local data `*b`
 }
index 355e8c914551c26952f41e3352b7349f3e5676bf..152abe109bca49913e799d2d38324c561d047ac1 100644 (file)
@@ -1,12 +1,11 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn foo(x: &usize) -> usize {
     *x
 }
 
 pub fn main() {
-    let p: Box<_> = box 22;
+    let p: Box<_> = Box::new(22);
     let r = foo(&*p);
     println!("r={}", r);
     assert_eq!(r, 22);
index 3bf049c151137a974c51c8c907b7761efe4a6046..adc6b1939da7f7e297a3c9f570668b5f8527644b 100644 (file)
@@ -1,12 +1,11 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn foo(x: &usize) -> usize {
     *x
 }
 
 pub fn main() {
-    let p: Box<_> = box 3;
+    let p: Box<_> = Box::new(3);
     let r = foo(&*p);
     assert_eq!(r, 3);
 }
index 0cbdc828c507fa5ecdcf9111ad0e1d6b28381317..428477e24899a8437733de8f6b04924a8e41e4ae 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
-
 trait X {}
 
+
+
 trait Iter {
     type Item: X;
 
@@ -18,7 +18,7 @@ fn bad1<T: Iter>(v: T) -> Box<dyn X + 'static>
 fn bad2<T: Iter>(v: T) -> Box<dyn X + 'static>
     where Box<T::Item> : X
 {
-    let item: Box<_> = box v.into_item();
+    let item: Box<_> = Box::new(v.into_item());
     Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
@@ -31,7 +31,7 @@ fn bad3<'a, T: Iter>(v: T) -> Box<dyn X + 'a>
 fn bad4<'a, T: Iter>(v: T) -> Box<dyn X + 'a>
     where Box<T::Item> : X
 {
-    let item: Box<_> = box v.into_item();
+    let item: Box<_> = Box::new(v.into_item());
     Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
index 5518c6a94b1d0bf546795d1fb5320ad2cdc5d7f6..2dc33d5671ff0597d14d9aa7fce9ff2a87a63ae2 100644 (file)
@@ -1,7 +1,7 @@
-#![feature(box_syntax)]
 #![allow(warnings)]
 
 trait A<T> { }
+
 struct B<'a, T:'a>(&'a (A<T>+'a));
 
 trait X { }
@@ -9,7 +9,7 @@ trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn f<'a, T:'static, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
-    box B(&*v) as Box<X> //~ ERROR cannot return value referencing local data `*v`
+    Box::new(B(&*v)) as Box<X> //~ ERROR cannot return value referencing local data `*v`
 }
 
 fn main() {}
index 8e119c4f5355fc8bbc1331db9d1fec8d3e92f6c2..5bfaeb295c352d1b771b202ae8ef44e302988cef 100644 (file)
@@ -1,10 +1,10 @@
 error[E0515]: cannot return value referencing local data `*v`
   --> $DIR/regions-close-object-into-object-1.rs:12:5
    |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^---^^^^^^^^^^^
-   |     |     |
-   |     |     `*v` is borrowed here
+LL |     Box::new(B(&*v)) as Box<X>
+   |     ^^^^^^^^^^^---^^^^^^^^^^^^
+   |     |          |
+   |     |          `*v` is borrowed here
    |     returns a value referencing data owned by the current function
 
 error: aborting due to previous error
index 882faf4ece316a34fc1dd781d153d99f2a5d08ee..410fab962f7208155c26a8f01becedd2c594c261 100644 (file)
@@ -1,20 +1,20 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-close-object-into-object-2.rs:10:5
+  --> $DIR/regions-close-object-into-object-2.rs:9:5
    |
 LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
    |      -- lifetime `'a` defined here
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
    |
    = help: consider replacing `'a` with `'static`
 
 error[E0515]: cannot return value referencing local data `*v`
-  --> $DIR/regions-close-object-into-object-2.rs:10:5
+  --> $DIR/regions-close-object-into-object-2.rs:9:5
    |
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^---^^^^^^^^^^^^^^^
-   |     |     |
-   |     |     `*v` is borrowed here
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          `*v` is borrowed here
    |     returns a value referencing data owned by the current function
 
 error: aborting due to 2 previous errors
index 7144ab5a24c51443ec36b8dffda63669e12317a0..9c41174e24d8db96cc84b0c58fc2a99948fe3f86 100644 (file)
@@ -1,13 +1,12 @@
-#![feature(box_syntax)]
-
 trait A<T> { }
+
 struct B<'a, T:'a>(&'a (dyn A<T> + 'a));
 
 trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
-    box B(&*v) as Box<dyn X> //~ ERROR E0759
+    Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759
 }
 
 fn main() { }
index 78d2371cf53b29f2ebb14535c88872e0bc57ed65..9a7df8c0188b193f6027a3a71a911dd88b450195 100644 (file)
@@ -1,10 +1,10 @@
 error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/regions-close-object-into-object-2.rs:10:11
+  --> $DIR/regions-close-object-into-object-2.rs:9:16
    |
 LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
    |                         ------------------ this data with lifetime `'a`...
-LL |     box B(&*v) as Box<dyn X>
-   |           ^^^ ...is captured here, requiring it to live as long as `'static`
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |                ^^^ ...is captured here, requiring it to live as long as `'static`
    |
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
    |
index 6f6b3a170027db2b0c996b1a7e772a0bb9970724..78d93b0ece5b656612590cc769beafbf8694d8f2 100644 (file)
@@ -1,14 +1,14 @@
-#![feature(box_syntax)]
 #![allow(warnings)]
 
 trait A<T> { }
+
 struct B<'a, T:'a>(&'a (A<T>+'a));
 
 trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn h<'a, T, U:'static>(v: Box<A<U>+'static>) -> Box<X+'static> {
-    box B(&*v) as Box<X> //~ ERROR cannot return value referencing local data `*v`
+    Box::new(B(&*v)) as Box<X> //~ ERROR cannot return value referencing local data `*v`
 }
 
 fn main() {}
index 9ea13638f5cad3506d382532a64fcab4905dd5e7..9f92c40e1e18d1d7f11e3cb07b363bee55198842 100644 (file)
@@ -1,10 +1,10 @@
 error[E0515]: cannot return value referencing local data `*v`
   --> $DIR/regions-close-object-into-object-3.rs:11:5
    |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^---^^^^^^^^^^^
-   |     |     |
-   |     |     `*v` is borrowed here
+LL |     Box::new(B(&*v)) as Box<X>
+   |     ^^^^^^^^^^^---^^^^^^^^^^^^
+   |     |          |
+   |     |          `*v` is borrowed here
    |     returns a value referencing data owned by the current function
 
 error: aborting due to previous error
index 93ac17810dae2015fd6fc92fa598524e722badf7..e2cd864ea020e63cd5540d134b0dce51ca759fd9 100644 (file)
@@ -1,39 +1,55 @@
 error[E0310]: the parameter type `U` may not live long enough
-  --> $DIR/regions-close-object-into-object-4.rs:10:5
+  --> $DIR/regions-close-object-into-object-4.rs:9:5
    |
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^^^^^
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `U: 'static`...
+
+error[E0310]: the parameter type `U` may not live long enough
+  --> $DIR/regions-close-object-into-object-4.rs:9:5
+   |
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `U: 'static`...
+
+error[E0310]: the parameter type `U` may not live long enough
+  --> $DIR/regions-close-object-into-object-4.rs:9:5
+   |
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `U: 'static`...
 
 error: lifetime may not live long enough
-  --> $DIR/regions-close-object-into-object-4.rs:10:5
+  --> $DIR/regions-close-object-into-object-4.rs:9:5
    |
 LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
    |      -- lifetime `'a` defined here
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
    |
    = help: consider replacing `'a` with `'static`
 
 error[E0515]: cannot return value referencing local data `*v`
-  --> $DIR/regions-close-object-into-object-4.rs:10:5
+  --> $DIR/regions-close-object-into-object-4.rs:9:5
    |
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^---^^^^^^^^^^^^^^^
-   |     |     |
-   |     |     `*v` is borrowed here
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          `*v` is borrowed here
    |     returns a value referencing data owned by the current function
 
 error[E0310]: the parameter type `U` may not live long enough
-  --> $DIR/regions-close-object-into-object-4.rs:10:9
+  --> $DIR/regions-close-object-into-object-4.rs:9:14
    |
-LL |     box B(&*v) as Box<dyn X>
-   |         ^^^^^^
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |              ^^^^^^
    |
    = help: consider adding an explicit lifetime bound `U: 'static`...
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0310, E0515.
 For more information about an error, try `rustc --explain E0310`.
index 4c087f264f92b964010c16521d98fd6a97f92889..2a06a2b7c0513630af945507700c46592af52a26 100644 (file)
@@ -1,13 +1,12 @@
-#![feature(box_syntax)]
-
 trait A<T> { }
+
 struct B<'a, T:'a>(&'a (dyn A<T> + 'a));
 
 trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
-    box B(&*v) as Box<dyn X> //~ ERROR E0759
+    Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759
 }
 
 fn main() {}
index 8c94b44f20037c84df4b0b89c14d08beddf7f84b..a7a9b16b0801379c4dcb0bb40675ca230bb9b9ca 100644 (file)
@@ -1,10 +1,10 @@
 error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/regions-close-object-into-object-4.rs:10:11
+  --> $DIR/regions-close-object-into-object-4.rs:9:16
    |
 LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
    |                   ---------------- this data with lifetime `'a`...
-LL |     box B(&*v) as Box<dyn X>
-   |           ^^^ ...is captured here, requiring it to live as long as `'static`
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |                ^^^ ...is captured here, requiring it to live as long as `'static`
    |
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
    |
index 08ba1b17b56636a176e08492ca9f0b51213ef13c..7486e73e66ab31122bda6f9b0af5301668a2cc94 100644 (file)
@@ -1,29 +1,45 @@
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:5
    |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/regions-close-object-into-object-5.rs:17:5
+   |
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/regions-close-object-into-object-5.rs:17:5
+   |
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `T: 'static`...
 
 error[E0515]: cannot return value referencing local data `*v`
   --> $DIR/regions-close-object-into-object-5.rs:17:5
    |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^---^^^^^^^^^^^
-   |     |     |
-   |     |     `*v` is borrowed here
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          `*v` is borrowed here
    |     returns a value referencing data owned by the current function
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
+  --> $DIR/regions-close-object-into-object-5.rs:17:14
    |
-LL |     box B(&*v) as Box<X>
-   |         ^^^^^^
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |              ^^^^^^
    |
    = help: consider adding an explicit lifetime bound `T: 'static`...
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0310, E0515.
 For more information about an error, try `rustc --explain E0310`.
index ff35b9ada45cd379dd66bc40e5e806ce62f5e22d..5471c375b4990ddf903a171fb21679825955e69e 100644 (file)
@@ -1,6 +1,6 @@
-#![feature(box_syntax)]
 #![allow(warnings)]
 
+
 trait A<T>
 {
     fn get(&self) -> T { panic!() }
@@ -14,13 +14,14 @@ impl<'a, T> X for B<'a, T> {}
 
 fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
     // oh dear!
-    box B(&*v) as Box<X>
+    Box::new(B(&*v)) as Box<dyn X>
     //~^ ERROR the parameter type `T` may not live long enough
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
 }
 
 fn main() {}
index 5b692cdcc0ecc77ebc6444265cb2730e7b9c092a..83f8d20b9e1deaae136e32c6a2bdafef7b92c06b 100644 (file)
@@ -4,26 +4,41 @@ error[E0310]: the parameter type `T` may not live long enough
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/regions-close-object-into-object-5.rs:9:17
+   |
+LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
+   |                 ^^
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/regions-close-object-into-object-5.rs:17:5
+   |
+LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
+   |          - help: consider adding an explicit lifetime bound...: `T: 'static`
+LL |     // oh dear!
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |     ^^^^^^^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
+  --> $DIR/regions-close-object-into-object-5.rs:17:14
    |
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |         ^ ...so that the type `T` will meet its required lifetime bounds
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |              ^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
+  --> $DIR/regions-close-object-into-object-5.rs:17:14
    |
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |         ^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |              ^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
    |
 note: ...that is required by this bound
   --> $DIR/regions-close-object-into-object-5.rs:9:17
@@ -32,32 +47,32 @@ LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
    |                 ^^
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
+  --> $DIR/regions-close-object-into-object-5.rs:17:16
    |
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |           ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |                ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
+  --> $DIR/regions-close-object-into-object-5.rs:17:16
    |
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |           ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |                ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
+  --> $DIR/regions-close-object-into-object-5.rs:17:16
    |
 LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
-LL |     box B(&*v) as Box<X>
-   |           ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
+LL |     Box::new(B(&*v)) as Box<dyn X>
+   |                ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
index 3101d815881b17fcd6442581dcefd58cd99acd00..b576ae87011377d25a1a6f8c53a1554ef63fdc81 100644 (file)
@@ -1,16 +1,16 @@
 error[E0310]: the parameter type `A` may not live long enough
   --> $DIR/regions-close-over-type-parameter-1.rs:12:5
    |
-LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^
+LL |     Box::new(v) as Box<dyn SomeTrait + 'static>
+   |     ^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `A: 'static`...
 
 error[E0309]: the parameter type `A` may not live long enough
   --> $DIR/regions-close-over-type-parameter-1.rs:21:5
    |
-LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^
+LL |     Box::new(v) as Box<dyn SomeTrait + 'b>
+   |     ^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `A: 'b`...
 
index 6e708a5f70fbd828edd106b96fed18ea85042e00..52d18c5d7a6fa1f113d5fedc7b27197265fbe488 100644 (file)
@@ -1,24 +1,24 @@
-#![feature(box_syntax)]
-
 // Test for what happens when a type parameter `A` is closed over into
 // an object. This should yield errors unless `A` (and the object)
 // both have suitable bounds.
 
+
 trait SomeTrait {
     fn get(&self) -> isize;
 }
 
+
 fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
-    box v as Box<dyn SomeTrait + 'static>
+    Box::new(v) as Box<dyn SomeTrait + 'static>
     //~^ ERROR the parameter type `A` may not live long enough
 }
 
 fn make_object2<'a, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'a> {
-    box v as Box<dyn SomeTrait + 'a>
+    Box::new(v) as Box<dyn SomeTrait + 'a>
 }
 
 fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
-    box v as Box<dyn SomeTrait + 'b>
+    Box::new(v) as Box<dyn SomeTrait + 'b>
     //~^ ERROR the parameter type `A` may not live long enough
 }
 
index 50274b066df60039130b9ba55bd0272b0de0f885..063c3b19a19cccc5bb96ea39e08196eb838a6295 100644 (file)
@@ -3,16 +3,16 @@ error[E0310]: the parameter type `A` may not live long enough
    |
 LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
    |                 -- help: consider adding an explicit lifetime bound...: `A: 'static +`
-LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^ ...so that the type `A` will meet its required lifetime bounds
+LL |     Box::new(v) as Box<dyn SomeTrait + 'static>
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `A` may not live long enough
   --> $DIR/regions-close-over-type-parameter-1.rs:21:5
    |
 LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
    |                         -- help: consider adding an explicit lifetime bound...: `A: 'b +`
-LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^ ...so that the type `A` will meet its required lifetime bounds
+LL |     Box::new(v) as Box<dyn SomeTrait + 'b>
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error: aborting due to 2 previous errors
 
index 2fb9dcc4e9ec77c3c9b5f59c79b59aeaaeee8ab3..c2bd3bbf823d2b6f206a88cb492f7ab77762dc2b 100644 (file)
@@ -6,8 +6,8 @@ LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait +
    |                    |
    |                    lifetime `'a` defined here
 LL |     // A outlives 'a AND 'b...but not 'c.
-LL |     box v as Box<dyn SomeTrait + 'a>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'c`
+LL |     Box::new(v) as Box<dyn SomeTrait + 'a>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'c`
    |
    = help: consider adding the following bound: `'a: 'c`
 
index 26643e08985be6107d873e27a0c481a4d390cbba..fc7696e7e03201e3e9b8fdcaaef36dc1ffc9f056 100644 (file)
@@ -1,23 +1,23 @@
-#![feature(box_syntax)]
-
 // Various tests where we over type parameters with multiple lifetime
 // bounds.
 
+
 trait SomeTrait { fn get(&self) -> isize; }
 
+
 fn make_object_good1<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'a> {
     // A outlives 'a AND 'b...
-    box v as Box<dyn SomeTrait + 'a> // ...hence this type is safe.
+    Box::new(v) as Box<dyn SomeTrait + 'a> // ...hence this type is safe.
 }
 
 fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'b> {
     // A outlives 'a AND 'b...
-    box v as Box<dyn SomeTrait + 'b> // ...hence this type is safe.
+    Box::new(v) as Box<dyn SomeTrait + 'b> // ...hence this type is safe.
 }
 
 fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> {
     // A outlives 'a AND 'b...but not 'c.
-    box v as Box<dyn SomeTrait + 'a> //~ ERROR cannot infer an appropriate lifetime
+    Box::new(v) as Box<dyn SomeTrait + 'a> //~ ERROR cannot infer an appropriate lifetime
 }
 
 fn main() {
index bf29c76a0f0a8bcee9ea263faeb1c70a23224ec0..0cb0b24f108b0c07392e2028ffb792d3c60a8b30 100644 (file)
@@ -1,8 +1,8 @@
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
   --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5
    |
-LL |     box v as Box<dyn SomeTrait + 'a>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     Box::new(v) as Box<dyn SomeTrait + 'a>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 18:20...
   --> $DIR/regions-close-over-type-parameter-multiple.rs:18:20
@@ -12,8 +12,8 @@ LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait +
 note: ...so that the declared lifetime parameter bounds are satisfied
   --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5
    |
-LL |     box v as Box<dyn SomeTrait + 'a>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     Box::new(v) as Box<dyn SomeTrait + 'a>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: but, the lifetime must be valid for the lifetime `'c` as defined on the function body at 18:26...
   --> $DIR/regions-close-over-type-parameter-multiple.rs:18:26
    |
@@ -22,8 +22,8 @@ LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait +
 note: ...so that the types are compatible
   --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5
    |
-LL |     box v as Box<dyn SomeTrait + 'a>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     Box::new(v) as Box<dyn SomeTrait + 'a>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `Box<(dyn SomeTrait + 'c)>`
               found `Box<dyn SomeTrait>`
 
index 4b47ed8c6aeb7120ed4c56888112208bafa0d365..48aad9481bbead1072a0786f2519670856924fbe 100644 (file)
@@ -2,8 +2,6 @@
 // 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 {
@@ -13,7 +11,7 @@ fn get(&self) -> isize {
 }
 
 fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait+'a> {
-    box v as Box<dyn SomeTrait+'a>
+    Box::new(v) as Box<dyn SomeTrait+'a>
 }
 
 fn main() {
index 0a7e6625c735392e8d5b1ee5d78bb634bbbacb8a..a6cb56e3156d445209b39d98425bd27ac0faadb9 100644 (file)
@@ -3,7 +3,6 @@
 // Issue #3148.
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 struct A {
     value: B
@@ -81,7 +80,7 @@ pub fn main() {
                          v2: [23, 24, 25],
                          v3: vec![26, 27, 28],
                          v4: C { f: 29 },
-                         v5: box C { f: 30 },
+                         v5: Box::new(C { f: 30 }),
                          v6: Some(C { f: 31 })}};
 
     let p = get_v1(&a);
index 276a64b8e9a7bb537ddf85549d93d2815f706a64..a28bd14ba88f6ca949e79912591923f6adf0789c 100644 (file)
@@ -2,8 +2,6 @@
 // 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;
@@ -72,7 +70,7 @@ fn short<'b>(&'b self) -> isize {
 
 impl<'t> MakerTrait for Box<dyn Trait<'t>+'static> {
     fn mk() -> Box<dyn Trait<'t>+'static> {
-        let tup: Box<(isize, isize)> = box (4,5);
+        let tup: Box<(isize, isize)> = Box::new((4,5));
         tup as Box<dyn Trait>
     }
 }
index fd4690463e6667a6d8682807a9d63f9882e0ebfb..65f4c1b6a64877265ed987f2a8a67607a9a5e0fe 100644 (file)
@@ -1,10 +1,8 @@
 // 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;
+    let p: Box<_> = Box::new(3);
     assert_eq!(bar(foo(&*p)), 3);
 }
index f0ecc5de5456786169385ffa06ecc36cb2db0e59..dca26742dacc598cbb3e03472dbdc61e5d60733b 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn borrow<T>(x: &T) -> &T {x}
 
 pub fn main() {
-    let x: Box<_> = box 3;
+    let x: Box<_> = Box::new(3);
     loop {
         let y = borrow(&*x);
         assert_eq!(*x, *y);
index 453973d9c58c34c4b8bb568654e42b6d4fd26aa4..b4a050bf1ede08af06e7666a382a95d6ec9bf54d 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 struct Point {x: isize, y: isize}
 
@@ -9,7 +8,7 @@ fn x_coord(p: &Point) -> &isize {
 }
 
 pub fn main() {
-    let p: Box<_> = box Point {x: 3, y: 4};
+    let p: Box<_> = Box::new(Point {x: 3, y: 4});
     let xc = x_coord(&*p);
     assert_eq!(*xc, 3);
 }
index c8106f32c65c257f68071d359c1484d6276d83b4..3852a14d9f98e8a113f98225cca04ca4f7628ac4 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
     fn explicit() {
         fn test<F>(_x: Option<Box<F>>) where F: FnMut(Box<dyn for<'a> FnMut(&'a isize)>) {}
-        test(Some(box |_f: Box<dyn for<'a> FnMut(&'a isize)>| {}));
+        test(Some(Box::new(|_f: Box<dyn for<'a> 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<F>(_x: Option<Box<F>>) where F: FnMut(Box<dyn        FnMut(&   isize)>) {}
-        test(Some(box |_f: Box<dyn        FnMut(&   isize)>| {}));
+        test(Some(Box::new(|_f: Box<dyn        FnMut(&   isize)>| {})));
     }
 
     explicit();
index d1cbd279b65a52432f1a74e8bd492ca7912c6826..3df529c9f0dae8909d60e14eda1579abdab6edb4 100644 (file)
@@ -1,11 +1,11 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
+
 
 fn arg_item(box ref x: Box<isize>) -> &'static isize {
     x //~ ERROR cannot return value referencing function parameter
 }
 
-fn with<R, F>(f: F) -> R where F: FnOnce(Box<isize>) -> R { f(box 3) }
+fn with<R, F>(f: F) -> R where F: FnOnce(Box<isize>) -> R { f(Box::new(3)) }
 
 fn arg_closure() -> &'static isize {
     with(|box ref x| x) //~ ERROR cannot return value referencing function parameter
index aec05161c1afbca2d57e7fdf7c7836db6136b889..b1bdb813ac6aad8215a2262c4dafc1ec681b6fae 100644 (file)
@@ -9,8 +9,6 @@
 // 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<isize>
 }
index 9169d457d40514dda3334cfa23f844923d76d17c..94ffb85c9c9c5d214a2f3b7df49da18e2be0fde5 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 // Issue #12470.
 
 trait X {
@@ -31,9 +29,11 @@ fn make_a(p: &dyn X) -> A {
 }
 
 fn make_make_a<'a>() -> A<'a> {
-    let b: Box<B> = box B {
+
+    let b: Box<B> = Box::new(B {
         i: 1,
-    };
+    });
+
     let bb: &B = &*b;
     make_a(bb) //~ ERROR cannot return value referencing local data `*b`
 }
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-closure.rs b/src/test/ui/rfc-2091-track-caller/tracked-closure.rs
new file mode 100644 (file)
index 0000000..670c423
--- /dev/null
@@ -0,0 +1,154 @@
+// run-pass
+
+#![feature(stmt_expr_attributes)]
+#![feature(closure_track_caller)]
+#![feature(generator_trait)]
+#![feature(generators)]
+
+use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
+use std::panic::Location;
+
+type Loc = &'static Location<'static>;
+
+#[track_caller]
+fn mono_invoke_fn<F: Fn(&'static str, bool) -> (&'static str, bool, Loc)>(
+    val: &F
+) -> (&'static str, bool, Loc) {
+    val("from_mono", false)
+}
+
+#[track_caller]
+fn mono_invoke_fn_once<F: FnOnce(&'static str, bool) -> (&'static str, bool, Loc)>(
+    val: F
+) -> (&'static str, bool, Loc) {
+    val("from_mono", false)
+}
+
+#[track_caller]
+fn dyn_invoke_fn_mut(
+    val: &mut dyn FnMut(&'static str, bool) -> (&'static str, bool, Loc)
+) -> (&'static str, bool, Loc) {
+    val("from_dyn", false)
+}
+
+#[track_caller]
+fn dyn_invoke_fn_once(
+    val: Box<dyn FnOnce(&'static str, bool) -> (&'static str, bool, Loc)>
+) -> (&'static str, bool, Loc) {
+    val("from_dyn", false)
+}
+
+
+fn test_closure() {
+    let mut track_closure = #[track_caller] |first: &'static str, second: bool| {
+        (first, second, Location::caller())
+    };
+    let (first_arg, first_bool, first_loc) = track_closure("first_arg", true);
+    let first_line = line!() - 1;
+    assert_eq!(first_arg, "first_arg");
+    assert_eq!(first_bool, true);
+    assert_eq!(first_loc.file(), file!());
+    assert_eq!(first_loc.line(), first_line);
+    assert_eq!(first_loc.column(), 46);
+
+    let (dyn_arg, dyn_bool, dyn_loc) = dyn_invoke_fn_mut(&mut track_closure);
+    assert_eq!(dyn_arg, "from_dyn");
+    assert_eq!(dyn_bool, false);
+    // `FnMut::call_mut` does not have `#[track_caller]`,
+    // so this will not match
+    assert_ne!(dyn_loc.file(), file!());
+
+    let (dyn_arg, dyn_bool, dyn_loc) = dyn_invoke_fn_once(Box::new(track_closure));
+    assert_eq!(dyn_arg, "from_dyn");
+    assert_eq!(dyn_bool, false);
+    // `FnOnce::call_once` does not have `#[track_caller]`
+    // so this will not match
+    assert_ne!(dyn_loc.file(), file!());
+
+
+    let (mono_arg, mono_bool, mono_loc) = mono_invoke_fn(&track_closure);
+    let mono_line = line!() - 1;
+    assert_eq!(mono_arg, "from_mono");
+    assert_eq!(mono_bool, false);
+    assert_eq!(mono_loc.file(), file!());
+    assert_eq!(mono_loc.line(), mono_line);
+    assert_eq!(mono_loc.column(), 43);
+
+    let (mono_arg, mono_bool, mono_loc) = mono_invoke_fn_once(track_closure);
+    let mono_line = line!() - 1;
+    assert_eq!(mono_arg, "from_mono");
+    assert_eq!(mono_bool, false);
+    assert_eq!(mono_loc.file(), file!());
+    assert_eq!(mono_loc.line(), mono_line);
+    assert_eq!(mono_loc.column(), 43);
+
+    let non_tracked_caller = || Location::caller();
+    let non_tracked_line = line!() - 1; // This is the line of the closure, not its caller
+    let non_tracked_loc = non_tracked_caller();
+    assert_eq!(non_tracked_loc.file(), file!());
+    assert_eq!(non_tracked_loc.line(), non_tracked_line);
+    assert_eq!(non_tracked_loc.column(), 33);
+}
+
+
+#[track_caller]
+fn mono_generator<F: Generator<String, Yield = (&'static str, String, Loc), Return = ()>>(
+    val: Pin<&mut F>
+) -> (&'static str, String, Loc) {
+    match val.resume("Mono".to_string()) {
+        GeneratorState::Yielded(val) => val,
+        _ => unreachable!()
+    }
+}
+
+#[track_caller]
+fn dyn_generator(
+    val: Pin<&mut dyn Generator<String, Yield = (&'static str, String, Loc), Return = ()>>
+) -> (&'static str, String, Loc) {
+    match val.resume("Dyn".to_string()) {
+        GeneratorState::Yielded(val) => val,
+        _ => unreachable!()
+    }
+}
+
+fn test_generator() {
+    let generator = #[track_caller] |arg: String| {
+        yield ("first", arg.clone(), Location::caller());
+        yield ("second", arg.clone(), Location::caller());
+    };
+
+    let mut pinned = Box::pin(generator);
+    let (dyn_ret, dyn_arg, dyn_loc) = dyn_generator(pinned.as_mut());
+    assert_eq!(dyn_ret, "first");
+    assert_eq!(dyn_arg, "Dyn".to_string());
+    // The `Generator` trait does not have `#[track_caller]` on `resume`, so
+    // this will not match.
+    assert_ne!(dyn_loc.file(), file!());
+
+
+    let (mono_ret, mono_arg, mono_loc) = mono_generator(pinned.as_mut());
+    let mono_line = line!() - 1;
+    assert_eq!(mono_ret, "second");
+    // The generator ignores the argument to the second `resume` call
+    assert_eq!(mono_arg, "Dyn".to_string());
+    assert_eq!(mono_loc.file(), file!());
+    assert_eq!(mono_loc.line(), mono_line);
+    assert_eq!(mono_loc.column(), 42);
+
+    let non_tracked_generator = || { yield Location::caller(); };
+    let non_tracked_line = line!() - 1; // This is the line of the generator, not its caller
+    let non_tracked_loc = match Box::pin(non_tracked_generator).as_mut().resume(()) {
+        GeneratorState::Yielded(val) => val,
+        _ => unreachable!()
+    };
+    assert_eq!(non_tracked_loc.file(), file!());
+    assert_eq!(non_tracked_loc.line(), non_tracked_line);
+    assert_eq!(non_tracked_loc.column(), 44);
+
+}
+
+fn main() {
+    test_closure();
+    test_generator();
+}
index b3be41599a54534134980f9aea93d0bb9e546847..0d1cded36b62d7b5e4dc058bb8e88cb072d03b3d 100644 (file)
@@ -1,11 +1,11 @@
 // run-pass
 #![allow(unreachable_patterns)]
-#![feature(box_syntax, box_patterns)]
+#![feature(box_patterns)]
 
 struct Foo{}
 
 pub fn main() {
-    let b = box Foo{};
+    let b = Box::new(Foo{});
     let box f = &b;
     let _: &Foo = f;
 
index 03f72a5513c20b294ca8b3ec2af35732612c5cba..8f6bed3b0cd6e01ba7b5f0e8c1b0ed2050a3f546 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(box_syntax)]
 
 #[derive(Copy, Clone)]
 struct LM { resize_at: usize, size: usize }
@@ -24,6 +23,6 @@ pub fn len(&mut self) -> usize {
 }
 
 pub fn main() {
-    let mut m: Box<_> = box linear_map::<(),()>();
+    let mut m: Box<_> = Box::new(linear_map::<(),()>());
     assert_eq!(m.len(), 0);
 }
index 0050bc7124d7183da5136ceb4b99d802b8e52700..250ea12e57c81f2345d773a42621aa733d9b5dfc 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 trait Foo {
     fn f(self: Box<Self>);
@@ -16,7 +15,7 @@ fn f(self: Box<S>) {
 }
 
 pub fn main() {
-    let x = box S { x: 3 };
+    let x = Box::new(S { x: 3 });
     let y = x as Box<dyn Foo>;
     y.f();
 }
index 6d19d33b6fee9bed347f6b25c55eb7ab8c95c607..873c3621a3bce35dfa4563db8b91894296c6a077 100644 (file)
@@ -3,8 +3,6 @@
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
 
-#![feature(box_syntax)]
-
 static tau: f64 = 2.0*3.14159265358979323;
 
 struct Point {x: f64, y: f64}
@@ -64,7 +62,7 @@ pub fn spam(self) -> isize { self.x.a }
 impl Nus for thing { fn f(&self) {} }
 
 pub fn main() {
-    let y: Box<_> = box thing(A {a: 10});
+    let y: Box<_> = Box::new(thing(A {a: 10}));
     assert_eq!(y.clone().bar(), 10);
     assert_eq!(y.quux(), 10);
 
index 23d513e3fac075b5671cd23be996c936b859ac21..7eed3f056a25f10fb5d320478daea6bb62474711 100644 (file)
@@ -5,8 +5,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 struct Foo;
 
 // Test uses on inherent impl.
@@ -57,14 +55,14 @@ fn bar(_x: Self, _y: &Self, _z: Box<Self>, _: Self::SuperQux) -> Self {
         let _: Self::SuperQux = true;
         let _: <Self as SuperBar>::SuperQux = true;
 
-        box Baz { f: 42 }
+        Box::new(Baz { f: 42 })
     }
 }
 
 fn main() {
-    let _: Foo = Foo::foo(Foo, &Foo, box Foo);
-    let _: Box<Baz<isize>> = Bar::bar(box Baz { f: 42 },
-                                      &box Baz { f: 42 },
-                                      box box Baz { f: 42 },
+    let _: Foo = Foo::foo(Foo, &Foo, Box::new(Foo));
+    let _: Box<Baz<isize>> = Bar::bar(Box::new(Baz { f: 42 }),
+                                      &Box::new(Baz { f: 42 }),
+                                      Box::new(Box::new(Baz { f: 42 })),
                                       true);
 }
index 82c5f58f0208fa6520782e9f877f90a03ceac5d1..45e122c8d77a0eca273f9a1ec2030e10e9da342b 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 struct X {
     a: isize
@@ -30,7 +29,7 @@ pub fn main() {
     let new_x = x.change();
     assert_eq!(new_x.a, 55);
 
-    let x: Box<_> = box new_x;
+    let x: Box<_> = Box::new(new_x);
     let new_x = x.change_again();
     assert_eq!(new_x.a, 45);
 }
index 88e8614683227117abbb41dac3d7d69e87dc998b..9595ebf9601fb89e335b9233e0cb215f3236742d 100644 (file)
@@ -2,13 +2,12 @@
 // Ensure assigning an owned or managed variable to itself works. In particular,
 // that we do not glue_drop before we glue_take (#3290).
 
-#![feature(box_syntax)]
 #![allow(dead_code)]
 
 use std::rc::Rc;
 
 pub fn main() {
-   let mut x: Box<_> = box 3;
+   let mut x: Box<_> = Box::new(3);
    x = x;
    assert_eq!(*x, 3);
 
index 0aaaa7d47c3c1eef0bcf8066e2e08218136a495b..d83af14d354fbe8d7dd79d30bb9ab5018efcd8d0 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 #![allow(dead_code)]
 
 #[derive(Copy, Clone)]
@@ -37,13 +36,13 @@ fn baz(self: Bar<T>, x: isize) -> isize {
 }
 
 fn main() {
-    let foo: Box<_> = box Foo {
+    let foo: Box<_> = Box::new(Foo {
         f: 1,
-    };
+    });
     println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
-    let bar: Box<_> = box Bar {
+    let bar: Box<_> = Box::new(Bar {
         f: 1,
-    };
+    });
     println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
     let bar: Box<Bar<isize>> = bar;
     println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
index 695f06ecddafb40887d20784a038737768b34e46..71e57d8c1fa1b50471bb621acf9b07b5ae3a0b25 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 struct X {
     a: isize
@@ -17,7 +16,7 @@ fn change(mut self: Box<X>) -> Box<X> {
 }
 
 pub fn main() {
-    let x: Box<_> = box X { a: 32 };
+    let x: Box<_> = Box::new(X { a: 32 });
     let new_x = x.change();
     assert_eq!(new_x.a, 55);
 }
index e74620f8900c08922d1bb81abc0ff2788e913d69..66fd68a9f236216f3a0e0f001a6d50afbf5b7fdb 100644 (file)
@@ -1,9 +1,9 @@
 // Test that shadowed lifetimes generate an error.
 
-#![feature(box_syntax)]
 
 struct Foo<T>(T);
 
+
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
     //~^ ERROR the name `T` is already used
index c461f825d99a481c30546bb0ca1d3f735c32faad..7920ae0b26ccaf6587a26c22ff5c286cf42cd2d4 100644 (file)
@@ -1,8 +1,8 @@
-#![feature(box_syntax)]
-
 fn test(_x: &mut String) {}
+
 fn test2(_x: &mut i32) {}
 
+
 fn main() {
     let x: usize = String::new();
     //~^ ERROR E0308
@@ -14,7 +14,7 @@ fn main() {
     test2(&y);
     //~^ ERROR E0308
     let f;
-    f = box f;
+    f = Box::new(f);
     //~^ ERROR E0308
 
     let s = &mut String::new();
index 2487684c1dd7f62f74c3b1cf4074e5ef8fe9816d..74caae8645c1d01e70d24307132e147ed9d459a9 100644 (file)
@@ -37,13 +37,10 @@ LL |     test2(&y);
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:17:9
    |
-LL |     f = box f;
-   |         ^^^^^ cyclic type of infinite size
-   |
-help: try using a conversion method
-   |
-LL |     f = (box f).to_string();
-   |         +     +++++++++++++
+LL |     f = Box::new(f);
+   |         ^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
+   |         |
+   |         cyclic type of infinite size
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:21:9
index 0f6472b05f7aae7a228983c17c5ebf6bed70db45..d9c08fbdd0f15e2521ad5967f3b3a9abbd9c77b1 100644 (file)
@@ -1,10 +1,10 @@
-#![feature(box_syntax, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
 fn main() {
     let r = {
-        let x: Box<_> = box 42;
+        let x: Box<_> = Box::new(42);
         let f = to_fn_once(move|| &x); //~ ERROR cannot return reference to local data `x`
         f()
     };
index e34f84683bbc7777b994f55dc7f737c7e87dfeb1..16b4cc2586273f98f1fc0c8a67ecf4996b7cc052 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 fn id<T>(x: T) -> T { x }
 
 trait Foo { }
@@ -7,10 +5,12 @@ trait Foo { }
 impl<'a> Foo for &'a isize { }
 
 fn main() {
+
     let blah;
+
     {
         let ss: &isize = &id(1);
         //~^ ERROR temporary value dropped while borrowed
-        blah = box ss as Box<dyn Foo>;
+        blah = Box::new(ss) as Box<dyn Foo>;
     }
 }
index 29083154b899130abb98560220adf58b22f1ab2e..aca3972cb6c55dc5a127d3c73dc4f2f52d10ef76 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 // Test for what happens when a type parameter `A` is closed over into
 // an object. This should yield errors unless `A` (and the object)
 // both have suitable bounds.
@@ -7,14 +5,16 @@
 trait Foo { fn get(&self); }
 
 impl<A> Foo for A {
-    fn get(&self) { }
+    fn get(&self) {
+    }
 }
 
 fn repeater3<'a,A:'a>(v: A) -> Box<dyn Foo + 'a> {
-    box v as Box<dyn Foo+'a>
+    Box::new(v) as Box<dyn Foo+'a>
 }
 
 fn main() {
+
     // Error results because the type of is inferred to be
     // ~Repeat<&'blk isize> where blk is the lifetime of the block below.
 
index f133133b3365038fbafbd29a56a45544aa05473e..d70706e5764f636bd48ab1e9ea68cf9269f9276d 100644 (file)
@@ -1,12 +1,12 @@
-#![feature(box_syntax)]
-
 fn id<T>(x: T) -> T { x }
 
 fn f<T:'static>(_: T) {}
 
 fn main() {
-    let x: Box<_> = box 3;
+
+    let x: Box<_> = Box::new(3);
     f(x);
+
     let x = &id(3); //~ ERROR temporary value dropped while borrowed
     f(x);
 }
index bf1ba8a643fea8f89950724a933b5d34598552da..f870096fdd44a798411b1a8f6aee5898848f1a12 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // aux-build:cci_class_cast.rs
 
-#![feature(box_syntax)]
-
 extern crate cci_class_cast;
 
 use std::string::ToString;
@@ -15,6 +13,6 @@ fn print_out(thing: Box<dyn ToString>, expected: String) {
 }
 
 pub fn main() {
-  let nyan: Box<dyn ToString> = box cat(0, 2, "nyan".to_string()) as Box<dyn ToString>;
+  let nyan: Box<dyn ToString> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 947690b51f422ab70ec1bfb46dd4eb83adbb1321..3d6da1cc280243d2208be1338bcf636345fb0689 100644 (file)
@@ -2,8 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-#![feature(box_syntax)]
-
 use std::fmt;
 
 struct cat {
@@ -60,6 +58,6 @@ fn print_out(thing: Box<dyn ToString>, expected: String) {
 }
 
 pub fn main() {
-  let nyan: Box<dyn ToString> = box cat(0, 2, "nyan".to_string()) as Box<dyn ToString>;
+  let nyan: Box<dyn ToString> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 77419e1132dc9ce0fd2fe1681c0d5c6feb0e0652..53892a4e0aeb46418848d9ef82f24e4d4a124fbe 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 /*!
  * This is a regression test for a bug in LLVM, fixed in upstream r179587,
@@ -9,7 +8,7 @@
 
 enum List<X> { Nil, Cons(X, Box<List<X>>) }
 pub fn main() {
-    match List::Cons(10, box List::Nil) {
+    match List::Cons(10, Box::new(List::Nil)) {
         List::Cons(10, _) => {}
         List::Nil => {}
         _ => panic!()
index 0448f0719589dceeceac3c3b383d90cf9eee1bf5..c54be7f5dff0d9497668de34e60c7a8d062cf45c 100644 (file)
@@ -1,5 +1,5 @@
 // edition:2018
-// compile-flags: -Cincremental=tmp/issue-72766
+// incremental
 
 pub struct SadGirl;
 
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.fixed b/src/test/ui/suggestions/missing-type-param-used-in-param.fixed
new file mode 100644 (file)
index 0000000..cc41200
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn two_type_params<A, B>(_: B) {}
+
+fn main() {
+    two_type_params::<String, _>(100); //~ ERROR this function takes 2 generic arguments
+    two_type_params::<String, _>(100);
+}
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.rs b/src/test/ui/suggestions/missing-type-param-used-in-param.rs
new file mode 100644 (file)
index 0000000..1928633
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn two_type_params<A, B>(_: B) {}
+
+fn main() {
+    two_type_params::<String>(100); //~ ERROR this function takes 2 generic arguments
+    two_type_params::<String, _>(100);
+}
diff --git a/src/test/ui/suggestions/missing-type-param-used-in-param.stderr b/src/test/ui/suggestions/missing-type-param-used-in-param.stderr
new file mode 100644 (file)
index 0000000..4f7058a
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+  --> $DIR/missing-type-param-used-in-param.rs:6:5
+   |
+LL |     two_type_params::<String>(100);
+   |     ^^^^^^^^^^^^^^^   ------ supplied 1 generic argument
+   |     |
+   |     expected 2 generic arguments
+   |
+note: function defined here, with 2 generic parameters: `A`, `B`
+  --> $DIR/missing-type-param-used-in-param.rs:3:4
+   |
+LL | fn two_type_params<A, B>(_: B) {}
+   |    ^^^^^^^^^^^^^^^ -  -
+help: add missing generic argument
+   |
+LL |     two_type_params::<String, _>(100);
+   |                             +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
index 8c40b2a5f11d6420cea7a920cec9121bba3acdbb..1e598b9e709718cd3164434bded57c604e5d1e55 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::thread;
 
 pub fn main() { test05(); }
@@ -12,7 +10,7 @@ fn test05_start<F:FnOnce(isize)>(f: F) {
 }
 
 fn test05() {
-    let three: Box<_> = box 3;
+    let three: Box<_> = Box::new(3);
     let fn_to_send = move|n:isize| {
         println!("{}", *three + n); // will copy x into the closure
         assert_eq!(*three, 3);
index 458f5653885e99a4b7bd7f9e596064193d3be12f..a63903778026a42029a723fe7259e7118b9b7657 100644 (file)
@@ -2,15 +2,13 @@
 #![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::<usize>();
 
-    let x: Box<isize> = box 1;
+    let x: Box<isize> = Box::new(1);
     let x_in_parent = &(*x) as *const isize as usize;
 
     let t = thread::spawn(move || {
index 941f66c056104081da515f7994f1553eb62abd85..a1492c0b98237bcbc50c02d7052517cf780d5eec 100644 (file)
@@ -5,8 +5,6 @@
 
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::sync::Arc;
 use std::sync::mpsc::channel;
 use std::thread;
@@ -67,10 +65,11 @@ pub fn main() {
         swim_speed: 998,
         name: "alec_guinness".to_string(),
     };
-    let arc = Arc::new(vec![box catte  as Box<dyn Pet+Sync+Send>,
-                            box dogge1 as Box<dyn Pet+Sync+Send>,
-                            box fishe  as Box<dyn Pet+Sync+Send>,
-                            box dogge2 as Box<dyn Pet+Sync+Send>]);
+    let arc = Arc::new(vec![
+        Box::new(catte)  as Box<dyn Pet+Sync+Send>,
+        Box::new(dogge1) as Box<dyn Pet+Sync+Send>,
+        Box::new(fishe)  as Box<dyn Pet+Sync+Send>,
+        Box::new(dogge2) as Box<dyn Pet+Sync+Send>]);
     let (tx1, rx1) = channel();
     let arc1 = arc.clone();
     let t1 = thread::spawn(move|| { check_legs(arc1); tx1.send(()); });
index cba33af1f1aca1f9b8221b5bdd8c912c630c8ce6..e62742bac5c74a42be062055b33cffd58253b0bf 100644 (file)
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(unused_mut)]
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 
 use std::io::{self, Write};
 
index a9c194486fecb93e2ebdb0cdc8d590951998f231..dd882dce6663573b2525580c161a17f20255bd0d 100644 (file)
@@ -3,7 +3,6 @@
 // blanket impl for T:Copy coexists with an impl for Box<T>, because
 // Box does not impl Copy.
 
-#![feature(box_syntax)]
 
 trait Get {
     fn get(&self) -> Self;
@@ -20,7 +19,7 @@ fn get(&self) -> T { self.copy() }
 }
 
 impl Get for Box<i32> {
-    fn get(&self) -> Box<i32> { box get_it(&**self) }
+    fn get(&self) -> Box<i32> { Box::new(get_it(&**self)) }
 }
 
 fn get_it<T:Get>(t: &T) -> T {
index 8859fbe6afb7b4ef01c5a3595d30828d8fe61866..07d92f8f8a0164e9674c9e1bd334ff19949c8428 100644 (file)
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(box_syntax)]
-
 use std::collections::HashMap;
 
 trait Graph<Node, Edge> {
@@ -19,6 +17,6 @@ fn g(&self, _e: isize) {
 }
 
 pub fn main() {
-    let g : Box<HashMap<isize,isize>> = box HashMap::new();
+    let g : Box<HashMap<isize,isize>> = Box::new(HashMap::new());
     let _g2 : Box<dyn Graph<isize,isize>> = g as Box<dyn Graph<isize,isize>>;
 }
index 23b91f924b553055f6562153a2904bdd66224b63..8adb06ba3d04e0da04775b2e84c544f46077b678 100644 (file)
@@ -2,8 +2,6 @@
 #![allow(non_snake_case)]
 #![allow(non_camel_case_types)]
 
-#![feature(box_syntax)]
-
 trait repeat<A> { fn get(&self) -> A; }
 
 impl<A:Clone + 'static> repeat<A> for Box<A> {
@@ -13,11 +11,11 @@ fn get(&self) -> A {
 }
 
 fn repeater<A:Clone + 'static>(v: Box<A>) -> Box<dyn repeat<A>+'static> {
-    box v as Box<dyn repeat<A>+'static> // No
+    Box::new(v) as Box<dyn repeat<A>+'static> // No
 }
 
 pub fn main() {
     let x = 3;
-    let y = repeater(box x);
+    let y = repeater(Box::new(x));
     assert_eq!(x, y.get());
 }
index b92a2ab7b4bc2414ab9aaab2517088df6652b372..86a2094eee098578e4562e83dd2a1de2aeac7196 100644 (file)
@@ -4,8 +4,6 @@
 // Testing creating two vtables with the same self type, but different
 // traits.
 
-#![feature(box_syntax)]
-
 use std::any::Any;
 
 trait Wrap {
@@ -27,7 +25,7 @@ fn is<T:Any>(x: &dyn Any) -> bool {
 }
 
 fn main() {
-    let x = box 22isize as Box<dyn Wrap>;
+    let x = Box::new(22isize) as Box<dyn Wrap>;
     println!("x={}", x.get());
     let y = x.wrap();
 }
index c18754302b75b279af7165e3398a87cfdb5ac3ea..e5a96af3810de4121ee202554f81721b9b0dd5ca 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // test for #8664
 
-#![feature(box_syntax)]
-
 use std::marker;
 
 pub trait Trait2<A> {
@@ -38,6 +36,6 @@ fn method(&self, _x: Type<(u8,V)>) -> isize { 0 }
 }
 
 pub fn main() {
-    let a = box () as Box<dyn Trait<u8, u8>>;
+    let a = Box::new(()) as Box<dyn Trait<u8, u8>>;
     assert_eq!(a.method(Type::Constant((1, 2))), 0);
 }
index 183c779607c9510a09c1e948ea9811443e65b2cf..342928e882a556e0e9a8958041284e945a14ee6a 100644 (file)
@@ -1,6 +1,6 @@
-#![feature(box_syntax)]
-
 #[allow(non_camel_case_types)]
+
+
 trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
 impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah<X>(&self) {} }
 impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} }
@@ -10,7 +10,8 @@ fn main() {
     //~^ ERROR this associated function takes 0 generic arguments but 1
     10.blah::<i32, i32>();
     //~^ ERROR this associated function takes 1 generic argument but 2
-    (box 10 as Box<dyn bar>).dup();
+    (Box::new(10) as Box<dyn bar>).dup();
     //~^ ERROR E0038
     //~| ERROR E0038
+    //~| ERROR E0038
 }
index d943b48fd0082115045e051a5f884cf56b545fe3..77ea4e4e974ebf06c36175f8cd48d50821840f0c 100644 (file)
@@ -27,10 +27,27 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |                                       ^^^^ -
 
 error[E0038]: the trait `bar` cannot be made into an object
-  --> $DIR/test-2.rs:13:16
+  --> $DIR/test-2.rs:13:22
    |
-LL |     (box 10 as Box<dyn bar>).dup();
-   |                ^^^^^^^^^^^^ `bar` cannot be made into an object
+LL |     (Box::new(10) as Box<dyn bar>).dup();
+   |                      ^^^^^^^^^^^^ `bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/test-2.rs:4:30
+   |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |       ---                    ^^^^     ^^^^ ...because method `blah` has generic type parameters
+   |       |                      |
+   |       |                      ...because method `dup` references the `Self` type in its return type
+   |       this trait cannot be made into an object...
+   = help: consider moving `dup` to another trait
+   = help: consider moving `blah` to another trait
+
+error[E0038]: the trait `bar` cannot be made into an object
+  --> $DIR/test-2.rs:13:5
+   |
+LL |     (Box::new(10) as Box<dyn bar>).dup();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `bar` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $DIR/test-2.rs:4:30
@@ -46,8 +63,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/test-2.rs:13:6
    |
-LL |     (box 10 as Box<dyn bar>).dup();
-   |      ^^^^^^ `bar` cannot be made into an object
+LL |     (Box::new(10) as Box<dyn bar>).dup();
+   |      ^^^^^^^^^^^^ `bar` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $DIR/test-2.rs:4:30
@@ -62,7 +79,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn bar>>` for `Box<{integer}>`
    = note: required by cast to type `Box<dyn bar>`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
 For more information about an error, try `rustc --explain E0038`.
index 277d9eabe4fb2ce7737c333e2da5c1e565854462..6d88002540c1ac43c355241244183a1ec04834fa 100644 (file)
@@ -1,5 +1,5 @@
 // run-pass
-#![feature(box_syntax, trait_upcasting)]
+#![feature(trait_upcasting)]
 #![allow(incomplete_features)]
 
 struct Test {
@@ -8,6 +8,6 @@ struct Test {
 
 fn main() {
     let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
-    let mut test = box Test { func: closure };
+    let mut test = Box::new(Test { func: closure });
     (test.func)();
 }
index 86b3f87d34d03c73eea9fd33e583e13da477c40d..c0147e56c9364a6bb2d3f99d8c1f014a20768539 100644 (file)
@@ -9,7 +9,7 @@ note: ...which requires type-checking `m::bar`...
    |
 LL |         is_send(foo());
    |         ^^^^^^^
-   = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`...
+   = note: ...which requires evaluating trait selection obligation `impl core::fmt::Debug: core::marker::Send`...
    = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
 note: cycle used when checking item types in module `m`
   --> $DIR/auto-trait-leakage3.rs:6:1
index a15074c35936bb2d10cd04ac5d8b5cb27908c086..579067340e85cb72df1cb5775ab0d5df604afdf9 100644 (file)
@@ -7,6 +7,7 @@ trait TraitWithAssoc {
 }
 
 type Foo<V> = impl Trait<V>;
+//~^ ERROR could not find defining uses
 
 trait Trait<U> {}
 
@@ -14,5 +15,9 @@ impl<W> Trait<W> for () {}
 
 fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
     //~^ ERROR non-defining opaque type use in defining scope
+    //~| ERROR non-defining opaque type use in defining scope
+    //~| ERROR non-defining opaque type use in defining scope
+    //~| ERROR `T` is part of concrete type but not used in parameter list
+    //~| ERROR `T` is part of concrete type but not used in parameter list
     ()
 }
index c9d6a43b9094ace0c5ea08b930d92eca1f44439a..a77c0000f12e1a0571b4a3710747e7104226243f 100644 (file)
@@ -1,8 +1,34 @@
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/bound_reduction2.rs:16:60
+   |
+LL |   fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+   |  ____________________________________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     ()
+LL | | }
+   | |_^
+
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/bound_reduction2.rs:16:60
+   |
+LL |   fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+   |  ____________________________________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     ()
+LL | | }
+   | |_^
+
 error: non-defining opaque type use in defining scope
-  --> $DIR/bound_reduction2.rs:15:46
+  --> $DIR/bound_reduction2.rs:16:1
    |
 LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   |                                              ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
   --> $DIR/bound_reduction2.rs:9:10
@@ -10,5 +36,35 @@ note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
 LL | type Foo<V> = impl Trait<V>;
    |          ^
 
-error: aborting due to previous error
+error: non-defining opaque type use in defining scope
+  --> $DIR/bound_reduction2.rs:16:1
+   |
+LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: used non-generic type `_` for generic parameter
+  --> $DIR/bound_reduction2.rs:9:10
+   |
+LL | type Foo<V> = impl Trait<V>;
+   |          ^
+
+error: non-defining opaque type use in defining scope
+  --> $DIR/bound_reduction2.rs:16:1
+   |
+LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: used non-generic type `_` for generic parameter
+  --> $DIR/bound_reduction2.rs:9:10
+   |
+LL | type Foo<V> = impl Trait<V>;
+   |          ^
+
+error: could not find defining uses
+  --> $DIR/bound_reduction2.rs:9:15
+   |
+LL | type Foo<V> = impl Trait<V>;
+   |               ^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
 
index 31f992976b1898ccd7cc71773c6b95669560a24a..885aae619d6a2bf5249b79df995508a4a63b336b 100644 (file)
@@ -3,6 +3,7 @@
 fn main() {}
 
 type Two<'a, 'b> = impl std::fmt::Debug;
+//~^ ERROR could not find defining uses
 
 fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
     //~^ ERROR non-defining opaque type use
index 08b26b8fc1307de927f4d60bccb3e2675ce23791..b99c6a51f4b1d24faa3cf2984eb3d9ff09da53ec 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_lifetime_param.rs:7:26
+  --> $DIR/generic_duplicate_lifetime_param.rs:8:26
    |
 LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
    |                          ^^^^^^^^^^^
@@ -10,5 +10,11 @@ note: lifetime used multiple times
 LL | type Two<'a, 'b> = impl std::fmt::Debug;
    |          ^^  ^^
 
-error: aborting due to previous error
+error: could not find defining uses
+  --> $DIR/generic_duplicate_lifetime_param.rs:5:20
+   |
+LL | type Two<'a, 'b> = impl std::fmt::Debug;
+   |                    ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
index a4e40f516dcefd7bd9769f58d4cf479afc883a5f..33cd2f6ba07539da18608740f78f3efa94f4de54 100644 (file)
@@ -6,8 +6,11 @@ fn main() {}
 
 // test that unused generic parameters are ok
 type TwoTys<T, U> = impl Debug;
+//~^ ERROR could not find defining uses
 type TwoLifetimes<'a, 'b> = impl Debug;
+//~^ ERROR could not find defining uses
 type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+//~^ ERROR could not find defining uses
 
 fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
     //~^ ERROR non-defining opaque type use in defining scope
index 641cce26d99446027b948a3fb02c4f15f641ac8d..52c60d1777e49131ecfc4b132c9096dd71b700bb 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:12:30
+  --> $DIR/generic_duplicate_param_use.rs:15:30
    |
 LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
    |                              ^^^^^^^^^^^^
@@ -10,29 +10,47 @@ note: type used multiple times
 LL | type TwoTys<T, U> = impl Debug;
    |             ^  ^
 
+error: could not find defining uses
+  --> $DIR/generic_duplicate_param_use.rs:8:21
+   |
+LL | type TwoTys<T, U> = impl Debug;
+   |                     ^^^^^^^^^^
+
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:17:36
+  --> $DIR/generic_duplicate_param_use.rs:20:36
    |
 LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
    |                                    ^^^^^^^^^^^^^^^^^^^^
    |
 note: lifetime used multiple times
-  --> $DIR/generic_duplicate_param_use.rs:9:19
+  --> $DIR/generic_duplicate_param_use.rs:10:19
    |
 LL | type TwoLifetimes<'a, 'b> = impl Debug;
    |                   ^^  ^^
 
+error: could not find defining uses
+  --> $DIR/generic_duplicate_param_use.rs:10:29
+   |
+LL | type TwoLifetimes<'a, 'b> = impl Debug;
+   |                             ^^^^^^^^^^
+
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:22:50
+  --> $DIR/generic_duplicate_param_use.rs:25:50
    |
 LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
    |                                                  ^^^^^^^^^^^^^^^
    |
 note: constant used multiple times
-  --> $DIR/generic_duplicate_param_use.rs:10:22
+  --> $DIR/generic_duplicate_param_use.rs:12:22
    |
 LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
    |                      ^               ^
 
-error: aborting due to 3 previous errors
+error: could not find defining uses
+  --> $DIR/generic_duplicate_param_use.rs:12:50
+   |
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+   |                                                  ^^^^^^^^^^
+
+error: aborting due to 6 previous errors
 
index a74731df69515f05d454255d9746e4fed54d9845..04fb57b39c052c3467fb45d3a7a3ab6cde829cc1 100644 (file)
@@ -6,6 +6,7 @@ fn main() {}
 
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
+//~^ ERROR `T` doesn't implement `Debug`
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
     //~^ ERROR non-defining opaque type use in defining scope
index d87e8c5783b65e1020d8b275a000b90171239f26..fca9b70d1844173127303eb69e8b2ca171e5a9c3 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use2.rs:10:27
+  --> $DIR/generic_duplicate_param_use2.rs:11:27
    |
 LL | fn one<T: Debug>(t: T) -> Two<T, T> {
    |                           ^^^^^^^^^
@@ -10,5 +10,17 @@ note: type used multiple times
 LL | type Two<T, U> = impl Debug;
    |          ^  ^
 
-error: aborting due to previous error
+error[E0277]: `T` doesn't implement `Debug`
+  --> $DIR/generic_duplicate_param_use2.rs:8:18
+   |
+LL | type Two<T, U> = impl Debug;
+   |                  ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+   |           +++++++++++++++++
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
index 0597b8385d25255673bdc496fad0fd92b64f9fc5..1a755d3902612f125a17b5f5477634743baf941a 100644 (file)
@@ -6,6 +6,7 @@ fn main() {}
 
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
+//~^ ERROR `T` doesn't implement `Debug`
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
     //~^ ERROR non-defining opaque type use in defining scope
@@ -17,5 +18,6 @@ fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
 }
 
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
+    //~^ ERROR concrete type differs from previous defining opaque type use
     u
 }
index 711de855f0d10978edf72e5311010b57b21d8bb2..90b04c043a00ccb1d0fa28571d9e7ffaaa54fdee 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use3.rs:10:27
+  --> $DIR/generic_duplicate_param_use3.rs:11:27
    |
 LL | fn one<T: Debug>(t: T) -> Two<T, T> {
    |                           ^^^^^^^^^
@@ -10,5 +10,29 @@ note: type used multiple times
 LL | type Two<T, U> = impl Debug;
    |          ^  ^
 
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/generic_duplicate_param_use3.rs:20:1
+   |
+LL | fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `U`
+   |
+note: previous use here
+  --> $DIR/generic_duplicate_param_use3.rs:16:1
+   |
+LL | fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `T` doesn't implement `Debug`
+  --> $DIR/generic_duplicate_param_use3.rs:8:18
+   |
+LL | type Two<T, U> = impl Debug;
+   |                  ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+   |           +++++++++++++++++
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
index e77c94988f73e4fd7614b1dd76e6563e06282746..50d95c83d58e644600976228707615908d42cec6 100644 (file)
@@ -6,6 +6,7 @@ fn main() {}
 
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
+//~^ ERROR `U` doesn't implement `Debug`
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
     //~^ ERROR non-defining opaque type use in defining scope
index fcf01f5164ae4aa770e52ada1ed7076194640d13..c4be2fa83f130fd068f7be5f14eddb4ac529ef93 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use4.rs:10:27
+  --> $DIR/generic_duplicate_param_use4.rs:11:27
    |
 LL | fn one<T: Debug>(t: T) -> Two<T, T> {
    |                           ^^^^^^^^^
@@ -10,5 +10,17 @@ note: type used multiple times
 LL | type Two<T, U> = impl Debug;
    |          ^  ^
 
-error: aborting due to previous error
+error[E0277]: `U` doesn't implement `Debug`
+  --> $DIR/generic_duplicate_param_use4.rs:8:18
+   |
+LL | type Two<T, U> = impl Debug;
+   |                  ^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+help: consider restricting type parameter `U`
+   |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+   |              +++++++++++++++++
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
index 7ee5f7b068f451c4ad64786a5d81bda7c57f5342..cf43085877f4c7864eefd534a8cb071c130989a6 100644 (file)
@@ -5,8 +5,11 @@
 fn main() {}
 
 type OneTy<T> = impl Debug;
+//~^ ERROR could not find defining uses
 type OneLifetime<'a> = impl Debug;
+//~^ ERROR could not find defining uses
 type OneConst<const X: usize> = impl Debug;
+//~^ ERROR could not find defining uses
 
 // Not defining uses, because they doesn't define *all* possible generics.
 
index 5b42f10a6ee34a19ab01ddc65a2d27876212e2ff..3aa42a25484d1dcc169f6ed6423f5b4ded454225 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:13:21
+  --> $DIR/generic_nondefining_use.rs:16:21
    |
 LL | fn concrete_ty() -> OneTy<u32> {
    |                     ^^^^^^^^^^
@@ -10,8 +10,14 @@ note: used non-generic type `u32` for generic parameter
 LL | type OneTy<T> = impl Debug;
    |            ^
 
+error: could not find defining uses
+  --> $DIR/generic_nondefining_use.rs:7:17
+   |
+LL | type OneTy<T> = impl Debug;
+   |                 ^^^^^^^^^^
+
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:18:27
+  --> $DIR/generic_nondefining_use.rs:21:27
    |
 LL | type OneLifetime<'a> = impl Debug;
    |                  -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
@@ -19,17 +25,29 @@ LL | type OneLifetime<'a> = impl Debug;
 LL | fn concrete_lifetime() -> OneLifetime<'static> {
    |                           ^^^^^^^^^^^^^^^^^^^^
 
+error: could not find defining uses
+  --> $DIR/generic_nondefining_use.rs:9:24
+   |
+LL | type OneLifetime<'a> = impl Debug;
+   |                        ^^^^^^^^^^
+
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:23:24
+  --> $DIR/generic_nondefining_use.rs:26:24
    |
 LL | fn concrete_const() -> OneConst<{ 123 }> {
    |                        ^^^^^^^^^^^^^^^^^
    |
 note: used non-generic constant `123_usize` for generic parameter
-  --> $DIR/generic_nondefining_use.rs:9:21
+  --> $DIR/generic_nondefining_use.rs:11:21
    |
 LL | type OneConst<const X: usize> = impl Debug;
    |                     ^
 
-error: aborting due to 3 previous errors
+error: could not find defining uses
+  --> $DIR/generic_nondefining_use.rs:11:33
+   |
+LL | type OneConst<const X: usize> = impl Debug;
+   |                                 ^^^^^^^^^^
+
+error: aborting due to 6 previous errors
 
index 955d1288a457d718689c5b5a44e209c701ee66d0..4c8bf2cfca11e75e9faee943e65c572560546444 100644 (file)
@@ -8,7 +8,6 @@ fn bar() -> Foo {
 }
 
 fn baz() -> Foo {
-    //~^ ERROR: concrete type differs from previous defining opaque type use
     Some(())
 }
 
index 53cdf9e5b385fc82f2209e64a6fc7dc007da30ab..0cdd4cc8dc3bac32435aa3e1debe2d2d70ca2f35 100644 (file)
@@ -4,18 +4,6 @@ error[E0282]: type annotations needed
 LL |     None
    |     ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`
 
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/incomplete-inference.rs:10:1
-   |
-LL | fn baz() -> Foo {
-   | ^^^^^^^^^^^^^^^ expected `[type error]`, got `Option<()>`
-   |
-note: previous use here
-  --> $DIR/incomplete-inference.rs:5:1
-   |
-LL | fn bar() -> Foo {
-   | ^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0282`.
index 4c5921c7f660ba6d51d9943008ababc928b1da19..e12124664778ed249087f4e88bb0011577b7e323 100644 (file)
@@ -9,7 +9,7 @@ note: ...which requires type-checking `m::bar`...
    |
 LL |         is_send(foo()); // Today: error
    |         ^^^^^^^
-   = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`...
+   = note: ...which requires evaluating trait selection obligation `impl core::fmt::Debug: core::marker::Send`...
    = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
 note: cycle used when checking item types in module `m`
   --> $DIR/inference-cycle.rs:4:1
index 37a2f28ce074fed466fbb7dcb3f4b95ef7a0a7cd..9d2ba849c8667539ae6a40efbfb3505387ac0cbd 100644 (file)
@@ -11,6 +11,7 @@ impl Bug for &() {
 
     const FUN: fn() -> Self::Item = || ();
     //~^ ERROR the trait bound `(): Bug` is not satisfied
+    //~| ERROR non-defining opaque type use in defining scope
 }
 
 fn main() {}
index 1710e07644d647e3b698b4fe60fbf10997c44952..62ab7eb456010c8d166c7640c89ec19b532b55c3 100644 (file)
@@ -16,7 +16,16 @@ LL |     const FUN: fn() -> Self::Item = || ();
    = help: the following implementations were found:
              <&() as Bug>
 
-error: aborting due to 2 previous errors
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-60371.rs:12:37
+   |
+LL | impl Bug for &() {
+   |              - cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL |     const FUN: fn() -> Self::Item = || ();
+   |                                     ^^^^^
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0658.
 For more information about an error, try `rustc --explain E0277`.
index 78def0d1136de8c5e7d0c0afde4b3a57ce2bbe2e..44dcec2c3da98f3ca47adaed7e089a8c88593ac1 100644 (file)
@@ -6,6 +6,7 @@ trait IterBits {
 }
 
 type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+//~^ ERROR could not find defining uses
 
 impl<T: Copy, E> IterBits for T
 where
index 66fa862ef9d7aa5e827a55eb8ed456a1d53f7baf..6b73fbef011ec8483e3b748637f32f905223ddfa 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/issue-60564.rs:19:34
+  --> $DIR/issue-60564.rs:20:34
    |
 LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
    |                                  ^^^^^^^^^^^^^^
@@ -10,5 +10,11 @@ note: used non-generic type `u8` for generic parameter
 LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
    |                         ^
 
-error: aborting due to previous error
+error: could not find defining uses
+  --> $DIR/issue-60564.rs:8:30
+   |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
new file mode 100644 (file)
index 0000000..2e63540
--- /dev/null
@@ -0,0 +1,14 @@
+// Regression test for issue #68368
+// Ensures that we don't ICE when emitting an error
+// for a non-defining use when lifetimes are involved
+
+#![feature(type_alias_impl_trait)]
+trait Trait<T> {}
+type Alias<'a, U> = impl Trait<U>;
+//~^ ERROR could not find defining uses
+fn f<'a>() -> Alias<'a, ()> {}
+//~^ ERROR non-defining opaque type use in defining scope
+
+fn main() {}
+
+impl<X> Trait<X> for () {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
new file mode 100644 (file)
index 0000000..721f99a
--- /dev/null
@@ -0,0 +1,20 @@
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-68368-non-defining-use-2.rs:9:15
+   |
+LL | fn f<'a>() -> Alias<'a, ()> {}
+   |               ^^^^^^^^^^^^^
+   |
+note: used non-generic type `()` for generic parameter
+  --> $DIR/issue-68368-non-defining-use-2.rs:7:16
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                ^
+
+error: could not find defining uses
+  --> $DIR/issue-68368-non-defining-use-2.rs:7:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
index 3b6decbe9c65e5cf5e5d75123246fc66ebd33a01..3addd8dcc4fb3486e5aa91f515a011eb9ab166b8 100644 (file)
@@ -5,6 +5,7 @@
 #![feature(type_alias_impl_trait)]
 trait Trait<T> {}
 type Alias<'a, U> = impl Trait<U>;
+//~^ ERROR could not find defining uses
 fn f<'a>() -> Alias<'a, ()> {}
 //~^ ERROR non-defining opaque type use in defining scope
 
index c2fa54f50f881214050a05d210964a8c152bd080..f5b8fccf65d167779a5cc91b7185a6dd153bfec6 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/issue-68368-non-defining-use.rs:8:15
+  --> $DIR/issue-68368-non-defining-use.rs:9:15
    |
 LL | fn f<'a>() -> Alias<'a, ()> {}
    |               ^^^^^^^^^^^^^
@@ -10,5 +10,11 @@ note: used non-generic type `()` for generic parameter
 LL | type Alias<'a, U> = impl Trait<U>;
    |                ^
 
-error: aborting due to previous error
+error: could not find defining uses
+  --> $DIR/issue-68368-non-defining-use.rs:7:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
index bcd9aeff6b451a839dc74293e2505bcbb2d4f834..11a922443e64a33c2083c6786b8e05553f6a7566 100644 (file)
@@ -11,7 +11,6 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>)
 }
 
 fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
-    //~^ ERROR concrete type differs from previous defining opaque type
     (a, b)
     //~^ ERROR mismatched types
 }
index 3d943b77af57da8a7586a1d5a5ba97514ae8886c..bbe709dccab4eb6e9404d4b5cba860ad4a7a2592 100644 (file)
@@ -1,11 +1,10 @@
 error[E0308]: mismatched types
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
    |
 LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
    |      -                    - found type parameter
    |      |
    |      expected type parameter
-LL |
 LL |     (a, b)
    |         ^ expected type parameter `A`, found type parameter `B`
    |
@@ -14,18 +13,6 @@ LL |     (a, b)
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1
-   |
-LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]`
-   |
-note: previous use here
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1
-   |
-LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0308`.
index f29b980dfd0e578e0177ea2a574c3d18ff6b1c2d..107cd394579355d2d05b010c4615a592f13b1f35 100644 (file)
@@ -5,6 +5,7 @@
 fn main() {}
 
 type Two<T, U> = impl Debug;
+//~^ ERROR `T` doesn't implement `Debug`
 
 fn two<T: Debug>(t: T) -> Two<T, u32> {
     //~^ ERROR non-defining opaque type use in defining scope
@@ -26,6 +27,7 @@ impl Bar for u32 {
 }
 
 fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
+    //~^ ERROR concrete type differs from previous
     (t, <U as Bar>::FOO)
 }
 
index 2fa236b373a40e482f9b5249ee24a8e3215d590a..08e49845521c6ab18e3d7dd92a2fe77f8519df4e 100644 (file)
@@ -1,5 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/not_a_defining_use.rs:9:27
+  --> $DIR/not_a_defining_use.rs:10:27
    |
 LL | fn two<T: Debug>(t: T) -> Two<T, u32> {
    |                           ^^^^^^^^^^^
@@ -10,5 +10,30 @@ note: used non-generic type `u32` for generic parameter
 LL | type Two<T, U> = impl Debug;
    |             ^
 
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/not_a_defining_use.rs:29:1
+   |
+LL | fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
+   |
+note: previous use here
+  --> $DIR/not_a_defining_use.rs:15:1
+   |
+LL | fn three<T: Debug, U>(t: T) -> Two<T, U> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `T` doesn't implement `Debug`
+  --> $DIR/not_a_defining_use.rs:7:18
+   |
+LL | type Two<T, U> = impl Debug;
+   |                  ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = note: required because of the requirements on the impl of `Debug` for `(T, i8)`
+help: consider restricting type parameter `T`
+   |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+   |           +++++++++++++++++
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
index 4b42fddaf5c88d7e66dbc66fa5eba3025a131ec2..3d87a089fca3a35299198ae32fc2a12b14654f9f 100644 (file)
@@ -4,8 +4,6 @@
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 fn p_foo<T>(_pinned: T) { }
 fn s_foo<T>(_shared: T) { }
 fn u_foo<T:Send>(_unique: T) { }
@@ -27,13 +25,13 @@ fn r(i:isize) -> r {
 pub fn main() {
     p_foo(r(10));
 
-    p_foo::<Box<_>>(box r(10));
-    p_foo::<Box<_>>(box 10);
+    p_foo::<Box<_>>(Box::new(r(10)));
+    p_foo::<Box<_>>(Box::new(10));
     p_foo(10);
 
-    s_foo::<Box<_>>(box 10);
+    s_foo::<Box<_>>(Box::new(10));
     s_foo(10);
 
-    u_foo::<Box<_>>(box 10);
+    u_foo::<Box<_>>(Box::new(10));
     u_foo(10);
 }
index 282d51a93df894b19fbc794408d22d1a98ad51b7..f982ad6a0ddc33da33d46d035fe368c166165021 100644 (file)
@@ -3,7 +3,6 @@
 #![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!
@@ -59,11 +58,11 @@ pub fn main() {
     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::new(leaf(magenta)), Box::new(leaf(cyan))),
+                &branch(Box::new(leaf(magenta)), Box::new(leaf(cyan)))));
 
-    assert!(!Equal::isEq(&branch(box leaf(magenta), box leaf(cyan)),
-                 &branch(box leaf(magenta), box leaf(magenta))));
+    assert!(!Equal::isEq(&branch(Box::new(leaf(magenta)), Box::new(leaf(cyan))),
+                 &branch(Box::new(leaf(magenta)), Box::new(leaf(magenta)))));
 
     println!("Assertions all succeeded!");
 }
index 8d1d22eb823004a242156a539fc76af16ec7a931..4400301e61ed7c3797ea306c08a837b22b50b3d0 100644 (file)
@@ -3,7 +3,6 @@
 #![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};
@@ -55,11 +54,11 @@ pub fn main() {
     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::new(leaf(magenta)), Box::new(leaf(cyan)))
+        .isEq(&branch(Box::new(leaf(magenta)), Box::new(leaf(cyan)))));
 
-    assert!(!branch(box leaf(magenta), box leaf(cyan))
-        .isEq(&branch(box leaf(magenta), box leaf(magenta))));
+    assert!(!branch(Box::new(leaf(magenta)), Box::new(leaf(cyan)))
+        .isEq(&branch(Box::new(leaf(magenta)), Box::new(leaf(magenta)))));
 
     println!("Assertions all succeeded!");
 }
index e836d33976a93114f8ec18331f17922e461d5169..cb1fac0bae6ae1798f231ba382ce76eb254d58f6 100644 (file)
@@ -1,9 +1,9 @@
-#![feature(box_syntax)]
-
 struct Foo {
     f: isize,
 }
 
+
+
 impl Foo {
     fn foo(self: isize, x: isize) -> isize {
         //~^ ERROR invalid `self` parameter type
@@ -48,12 +48,12 @@ fn dummy3(self: &&Bar<T>) {}
 }
 
 fn main() {
-    let foo = box Foo {
+    let foo = Box::new(Foo {
         f: 1,
-    };
+    });
     println!("{}", foo.foo(2));
-    let bar = box Bar {
+    let bar = Box::new(Bar {
         f: 1,
-    };
+    });
     println!("{} {}", bar.foo(2), bar.bar(2));
 }
index b2596e49aa78eecc8ea2e91f8a93e3e6d8a12aab..3f550fd04259f583b43de4d6068b623c61c223fa 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
-#![feature(box_syntax)]
 
 use std::ops::FnMut;
 
  fn make_adder(x: i32) -> Box<dyn FnMut(i32)->i32+'static> {
-    (box move |y: i32| -> i32 { x + y }) as
+    Box::new(move |y: i32| -> i32 { x + y }) as
         Box<dyn FnMut(i32)->i32+'static>
 }
 
index 58c726d2185c4d3d13ec6cfb6813933a17295877..f1573b6adf0ce0952577be747a15ef8ebdfaa3b5 100644 (file)
@@ -1,8 +1,8 @@
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
+
 #![deny(unreachable_patterns)]
 
 mod foo {
index d243b8f34dbcf045c558dca39341be0bb84d88f7..2c40dfc7a4b257bad296477b99662c271447e1bd 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 trait Foo {
     fn f(&self);
 }
@@ -18,8 +16,10 @@ fn f(&self) {
     }
 }
 
+
+
 fn main() {
-    let x = box Bar { x: 10 };
+    let x = Box::new(Bar { x: 10 });
     let y: Box<dyn Foo> = x as Box<dyn Foo>;
     let _z = y.clone(); //~ ERROR the method
 }
index 194698102377e117d4c898eed448984c560151ad..b742973ce327d856d309a56819a3e5ec1ab28e15 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let mut i: Box<_> = box 1;
+    let mut i: Box<_> = Box::new(1);
     // Should be a copy
     let mut j;
     j = i.clone();
index 32068e79df49cf8939bb3ac3e95e3720680e70f0..e7685b589ca8ee770e6bd7a9e075e513a7bdf44c 100644 (file)
@@ -1,11 +1,9 @@
 // run-pass
 #![allow(unused_assignments)]
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let i: Box<_> = box 1;
-    let mut j: Box<_> = box 2;
+    let i: Box<_> = Box::new(1);
+    let mut j: Box<_> = Box::new(2);
     // Should drop the previous value of j
     j = i;
     assert_eq!(*j, 1);
index 2d62ce59ad01257903878ca6dc9e4a895d5b63ae..d4932d8333ab7d3c4a9365208e8777182ca73124 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f<T>(t: T) -> T {
     let t1 = t;
@@ -7,6 +6,6 @@ fn f<T>(t: T) -> T {
 }
 
 pub fn main() {
-    let t = f::<Box<_>>(box 100);
-    assert_eq!(t, box 100);
+    let t = f::<Box<_>>(Box::new(100));
+    assert_eq!(t, Box::new(100));
 }
index 5a88df071a0b97e088ae91f24cea3b6843109599..d598744f145b2a08bbc9b4d4d527dd7b82b62fa7 100644 (file)
@@ -1,9 +1,8 @@
 // run-pass
 #![allow(unused_mut)]
-#![feature(box_syntax)]
 
 pub fn main() {
     let mut i: Box<_>;
-    i = box 1;
+    i = Box::new(1);
     assert_eq!(*i, 1);
 }
index 0360646f1330e0973406b3ed8825c7701e069e56..64147e11f1c0c90a82336791eeaf38822c18767d 100644 (file)
@@ -1,11 +1,10 @@
 // run-pass
-#![feature(box_syntax)]
 
 struct J { j: isize }
 
 pub fn main() {
-    let i: Box<_> = box J {
+    let i: Box<_> = Box::new(J {
         j: 100
-    };
+    });
     assert_eq!(i.j, 100);
 }
index 5a3d17a84efc2f232de6fe7432b4a07d0b9831a0..ea6598a7f6b351518f14366724a0c48f016f6b2e 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box vec![100];
+    let i: Box<_> = Box::new(vec![100]);
     assert_eq!((*i)[0], 100);
 }
index 7bbc61d25ac780665a8db9ce4503eb26ab296f83..ee05dd5a31d5b5b268f2b014dff5b264e942aa49 100644 (file)
@@ -1,12 +1,11 @@
 // 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);
+    let i: Box<_> = Box::new(100);
+    assert_eq!(i, Box::new(100));
+    assert!(i < Box::new(101));
+    assert!(i <= Box::new(100));
+    assert!(i > Box::new(99));
+    assert!(i >= Box::new(99));
 }
index f24b3a8645f297eb31bce7645cb204590e8d8e6d..6c31ae99b8eefa492ad0db8482c88c3c2daad373 100644 (file)
@@ -4,12 +4,10 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
     enum t { t1(isize), t2(isize), }
 
-    let _x: Box<_> = box t::t1(10);
+    let _x: Box<_> = Box::new(t::t1(10));
 
     /*alt *x {
       t1(a) {
@@ -19,9 +17,9 @@ enum t { t1(isize), t2(isize), }
     }*/
 
     /*alt x {
-      box t1(a) {
+      Box::new(t1(a) {
         assert_eq!(a, 10);
-      }
+      })
       _ { panic!(); }
     }*/
 }
index 3df0f7d55fd5849a40c7d78c8bb45a900c962220..c566e79620a95f0f6beb4e9a590d5d39de5ac827 100644 (file)
@@ -2,10 +2,8 @@
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let _: Box<_> = box 100;
+    let _: Box<_> = Box::new(100);
 }
 
 fn vec() {
index 6ae95949e84da428a2c040ad9b185dab2dab8bae..5b9576fcc7a5b65c57badca295471b7c89eeea7d 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let mut i: Box<_> = box 1;
+    let mut i: Box<_> = Box::new(1);
     // Should be a copy
     let mut j = i.clone();
     *i = 2;
index 2c7b9d6054f44f7f1911d01af800c734bb3b1762..1d70860c7cec0b213ca04cd74dc0671a25595f78 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 1;
+    let i: Box<_> = Box::new(1);
     let j = i;
     assert_eq!(*j, 1);
 }
index 4a5ee56ea92828644d699e722c9a4856bef014bd..21187510ff0c5942719eddceda66a1cd0fab20d2 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
     let j = i;
     assert_eq!(*j, 100);
 }
index 0c6af0f7f97af2130b557ccd4b7b5157594ad960..33a1e9932b5d1beb07eef6cdbcd2fcfc56f67e00 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
     assert_eq!(*i, 100);
 }
index 9b9f95dfbcae608076fafd39f11f21c501dcc7b5..7207ac962953ebc53ac3764c4348dc76dcc11917 100644 (file)
@@ -1,10 +1,9 @@
 // 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};
+    let box Foo{ a, b } = Box::new(Foo { a: 100, b: 200 });
     assert_eq!(a + b, 300);
 }
index 0b7bda83b3fa18a68882a0b80919b7e1d36a0eae..2324f1e1a652f5c66100c462c578c2347a4a0d9a 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let _x: Box<_> = box vec![0,0,0,0,0];
+    let _x: Box<_> = Box::new(vec![0,0,0,0,0]);
 }
index ff33839e57ee27c757005d567bbb53222675696f..6d42df218fbfd03cde2deec15d7458e1065443b8 100644 (file)
@@ -1,11 +1,10 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f(i: Box<isize>) {
     assert_eq!(*i, 100);
 }
 
 pub fn main() {
-    let i = box 100;
+    let i = Box::new(100);
     f(i);
 }
index e8bb35e4eb0cf99698db036785de56dc446305cf..01510200b11b793d48d717c63cfb008fc9d57775 100644 (file)
@@ -1,12 +1,11 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f(i: &mut Box<isize>) {
-    *i = box 200;
+    *i = Box::new(200);
 }
 
 pub fn main() {
-    let mut i = box 100;
+    let mut i = Box::new(100);
     f(&mut i);
     assert_eq!(*i, 200);
 }
index 75f2a767f59baef301da208e69cc322525ab4845..b4f3bc4b294bace6a97a54305c61e2595858011b 100644 (file)
@@ -1,12 +1,11 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f(i: Box<isize>) {
     assert_eq!(*i, 100);
 }
 
 pub fn main() {
-    f(box 100);
-    let i = box 100;
+    f(Box::new(100));
+    let i = Box::new(100);
     f(i);
 }
index cd44cfa983661433a2bb0e0d8c1c8ba7981c0f2e..773a9bce1adb04e010d9eb8214283cb3b54365f1 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
-#![feature(box_syntax)]
 
 fn f() -> Box<isize> {
-    box 100
+    Box::new(100)
 }
 
 pub fn main() {
-    assert_eq!(f(), box 100);
+    assert_eq!(f(), Box::new(100));
 }
index 8d97ebe659097ba32e3fff0c96d46fa0626e1b0f..6daa06fb12de6407c1f6376962ef25a7103e9214 100644 (file)
@@ -2,12 +2,10 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-#![feature(box_syntax)]
-
 fn test1() {
     enum bar { u(Box<isize>), w(isize), }
 
-    let x = bar::u(box 10);
+    let x = bar::u(Box::new(10));
     assert!(match x {
       bar::u(a) => {
         println!("{}", a);
index 8907a8b20a7aefd3619042fa7c32c1b621381982..ce52d15ef1acb7ee7bf1e10cb0ea14b5fceafa57 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let mut a: Vec<Box<_>> = vec![box 10];
+    let mut a: Vec<Box<_>> = vec![Box::new(10)];
     let b = a.clone();
 
     assert_eq!(*a[0], 10);
index 528ea4fb870e85717a226b55d693b98db2f9521b..1e8d05e3d269f9f10ae58c7be2193658a980eaaa 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let vect : Vec<Box<_>> = vec![box 100];
-    assert_eq!(vect[0], box 100);
+    let vect : Vec<Box<_>> = vec![Box::new(100)];
+    assert_eq!(vect[0], Box::new(100));
 }
index c8a150522fd2e3884f5ef54867f3b273beb72ca7..d19605046e1bc349e49fa67283ef00f17fcc3af3 100644 (file)
@@ -1,8 +1,6 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let _i: Box<_> = box 100;
+    let _i: Box<_> = Box::new(100);
 }
index f369a1e2a190d3e1184d81923812e8404f241332..f02d0b50764ae9f0b9c061ebaeab0b3f2b87c903 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(box_syntax)]
 
 use std::cmp::PartialEq;
 use std::fmt::Debug;
@@ -14,11 +13,11 @@ fn g<T:Send + PartialEq>(i: T, j: T) {
         assert!(i != j);
     }
 
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(100);
     f(i, j);
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 101;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(101);
     g(i, j);
 }
 
@@ -32,11 +31,11 @@ fn g<T:PartialEq>(i: T, j: T) {
         assert!(i != j);
     }
 
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(100);
     f(i, j);
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 101;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(101);
     g(i, j);
 }
 
@@ -50,11 +49,11 @@ fn g<T:PartialEq>(i: T, j: T) {
         assert!(i != j);
     }
 
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(100);
     f(i, j);
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 101;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(101);
     g(i, j);
 }
 
index 279777177061d5b1f32b8108383b8b6ffefc4c0e..0715d16628f87cb991ecf52cb0bde7c03258d1cf 100644 (file)
@@ -1,7 +1,6 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
     println!("{}", i);
 }
index e1ea58b39ef50007984e14308154c58f3b527fb6..c0f5d8f90532dfcbc6b9a383b80179d5738cb09d 100644 (file)
@@ -1,11 +1,10 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 100;
-    let j: Box<_> = box 200;
+    let i: Box<_> = Box::new(100);
+    let j: Box<_> = Box::new(200);
     let j = i;
     assert_eq!(*j, 100);
 }
index 4f5de50b722f92229eb929f396a72e487bc20c5e..103af8e1f1e02bd4f481f872a60577473277743e 100644 (file)
@@ -1,9 +1,8 @@
 // run-pass
 #![allow(unused_mut)]
-#![feature(box_syntax)]
 
 pub fn main() {
     let mut i: Box<_>;
-    i = box 100;
+    i = Box::new(100);
     assert_eq!(*i, 100);
 }
index 0f6bff1432b3fd39d0c6a64eeeb250830dadeda1..40a2718e4e5f68ed2335b907b980b1427e15bdc2 100644 (file)
@@ -1,9 +1,8 @@
 // run-pass
 #![allow(unused_mut)]
-#![feature(box_syntax)]
 
 pub fn main() {
-    let i: Box<_> = box 100;
+    let i: Box<_> = Box::new(100);
     let mut j;
     j = i;
     assert_eq!(*j, 100);
index 176cf33d4889c0c499ad1197f2292efe74f94f5b..0367c08099a8326b61123ae4b6d1f151529ac765 100644 (file)
@@ -1,8 +1,7 @@
 // run-pass
-#![feature(box_syntax)]
 
 pub fn main() {
-    let mut i: Box<_> = box 0;
+    let mut i: Box<_> = Box::new(0);
     *i = 1;
     assert_eq!(*i, 1);
 }
index 84e8cdb32b84e588a03ed474451900fa53f1acb3..bb35a9b2d73e2cd55ac0e0a3e88e24419590b64a 100644 (file)
@@ -4,8 +4,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub trait EventLoop { fn foo(&self) {} }
 
 pub struct UvEventLoop {
@@ -15,6 +13,6 @@ pub struct UvEventLoop {
 impl EventLoop for UvEventLoop { }
 
 pub fn main() {
-    let loop_: Box<dyn EventLoop> = box UvEventLoop { uvio: 0 } as Box<dyn EventLoop>;
+    let loop_: Box<dyn EventLoop> = Box::new(UvEventLoop { uvio: 0 }) as Box<dyn EventLoop>;
     let _loop2_ = loop_;
 }
index c18e029b252cbb468887e217e6b752e44b4f56fc..9c73fd2204c382ed6f9c8b8c58f6adf8df66e0f0 100644 (file)
@@ -4,15 +4,15 @@
 #![allow(non_shorthand_field_patterns)]
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 struct Foo {a: isize, b: usize}
 
 enum bar { u(Box<Foo>), 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);
+    let v = match bar::u(Box::new(Foo{ a: 10, b: 40 })) {
+        bar::u(box Foo{ a: a, b: b }) => { a + (b as isize) }
+        _ => { 66 }
+    };
+    assert_eq!(v, 50);
 }
index e17b5a3ddb450996fc335267cdf220d800abf7cf..2e81f898d0c98e04b619f6deb2e8350917d2b501 100644 (file)
@@ -2,16 +2,15 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-#![feature(box_syntax)]
-
 enum bar { u(Box<isize>), w(isize), }
 
 pub fn main() {
-    assert!(match bar::u(box 10) {
-      bar::u(a) => {
-        println!("{}", a);
-        *a
-      }
-      _ => { 66 }
-    } == 10);
+    let v = match bar::u(10.into()) {
+        bar::u(a) => {
+            println!("{}", a);
+            *a
+        }
+        _ => { 66 }
+    };
+    assert_eq!(v, 10);
 }
index b32195ac274217b1a2cb5efb1ec57415613a4f8e..c2474d0e77214dca8b16898dd7c39343a4ae51aa 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
 
 #![feature(box_patterns)]
-#![feature(box_syntax)]
 
 fn simple() {
-    match box true {
+    match Box::new(true) {
       box true => { }
       _ => { panic!(); }
     }
index c8bddd246a8051aa6b2d0c120fad89a459cd631f..9f8ad9bb050430542106a076aa97abdf4c51fcee 100644 (file)
@@ -1,10 +1,9 @@
 // run-pass
-#![feature(box_syntax)]
 
 struct X { x: isize }
 
 pub fn main() {
-    let x: Box<_> = box X {x: 1};
+    let x: Box<_> = Box::new(X {x: 1});
     let bar = x;
     assert_eq!(bar.x, 1);
 }
index 22f0e6c3a49b03aa93d21e3bd38ada5da4d44207..23ddd2cdca25d0f333943ad8a3279e5427eef0f8 100644 (file)
@@ -2,13 +2,11 @@
 #![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<Box<usize>>, i: usize) {
-    tx.send(box i).unwrap();
+    tx.send(Box::new(i)).unwrap();
 }
 
 pub fn main() {
index a5c7561b9ae3cf652f43954916ae928adb8e4f83..431cc2be5d20e3d458af8403b7539d7453f40245 100644 (file)
@@ -1,11 +1,10 @@
 // run-pass
-#![feature(box_syntax)]
 
 use std::sync::mpsc::channel;
 
 pub fn main() {
     let (tx, rx) = channel::<Box<_>>();
-    tx.send(box 100).unwrap();
+    tx.send(Box::new(100)).unwrap();
     let v = rx.recv().unwrap();
-    assert_eq!(v, box 100);
+    assert_eq!(v, Box::new(100));
 }
index 33a6b3b3ed046ae86c482b2b3eeb782c22c907b5..4f33ff9a8a35e7fdb1a2364a3908e4dbd115f2d5 100644 (file)
@@ -1,12 +1,11 @@
 // run-pass
-#![feature(box_syntax)]
 
 use std::mem::swap;
 
 pub fn main() {
-    let mut i: Box<_> = box 100;
-    let mut j: Box<_> = box 200;
+    let mut i: Box<_> = Box::new(100);
+    let mut j: Box<_> = Box::new(200);
     swap(&mut i, &mut j);
-    assert_eq!(i, box 200);
-    assert_eq!(j, box 100);
+    assert_eq!(i, Box::new(200));
+    assert_eq!(j, Box::new(100));
 }
index be4406399fd0f7ba8ebefa0441bc16954d4f3286..bbeb00d5fed60c423cb0fc371710193f6f97d31c 100644 (file)
@@ -4,7 +4,6 @@
 #![allow(dead_code)]
 #![allow(unused_variables)]
 #![allow(unused_imports)]
-#![feature(box_syntax)]
 
 // Test sized-ness checking in substitution.
 
@@ -36,7 +35,7 @@ trait T2 {
 struct S;
 impl T2 for S {
     fn f() -> Box<S> {
-        box S
+        Box::new(S)
     }
 }
 fn f5<X: ?Sized+T2>(x: &X) {
@@ -51,7 +50,7 @@ trait T3 {
 }
 impl T3 for S {
     fn f() -> Box<S> {
-        box S
+        Box::new(S)
     }
 }
 fn f7<X: ?Sized+T3>(x: &X) {
index c5c5ed26c7384b263dcf857a844f6c118194b9d9..4d5e89575bef6b50d14cafacc22ab9f643b4fbed 100644 (file)
@@ -2,7 +2,7 @@
 // Test structs with always-unsized fields.
 
 #![allow(warnings)]
-#![feature(box_syntax, unsize, ptr_metadata)]
+#![feature(unsize, ptr_metadata)]
 
 use std::mem;
 use std::ptr;
@@ -58,7 +58,7 @@ struct Foo_<T> {
             f: [T; 3],
         }
 
-        let data: Box<Foo_<i32>> = box Foo_ { f: [1, 2, 3] };
+        let data: Box<Foo_<i32>> = Box::new(Foo_ { f: [1, 2, 3] });
         let x: &Foo<i32> = mem::transmute(slice::from_raw_parts(&*data, 3));
         assert_eq!(x.f.len(), 3);
         assert_eq!(x.f[0], 1);
@@ -69,7 +69,7 @@ struct Baz_ {
         }
 
         let data: Box<_> =
-            box Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
+            Box::new(Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] });
         let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5));
         assert_eq!(x.f1, 42);
         let chs: Vec<char> = x.f2.chars().collect();
@@ -84,9 +84,9 @@ struct Qux_ {
             f: St,
         }
 
-        let obj: Box<St> = box St { f: 42 };
+        let obj: Box<St> = Box::new(St { f: 42 });
         let obj: &Tr = &*obj;
-        let data: Box<_> = box Qux_ { f: St { f: 234 } };
+        let data: Box<_> = Box::new(Qux_ { f: St { f: 234 } });
         let x: &Qux = &*ptr::from_raw_parts::<Qux>((&*data as *const _).cast(), ptr::metadata(obj));
         assert_eq!(x.f.foo(), 234);
     }
index e9d4684736ebfecc8d209cfba2ffce585e012158..efaf10da4a99fa2b9fb12263700eeb809b794080 100644 (file)
@@ -1,10 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![feature(box_syntax)]
-
 pub fn main() {
-    let _x: Box<_> = box 1;
+    let _x: Box<_> = Box::new(1);
     let lam_move = || {};
     lam_move();
 }
index 37aee22f85dbb3eefb0aad3dce970dd20a46d52c..697434d47ebb217c4cceb0d9d14e0e851bd1b5fe 100644 (file)
@@ -6,10 +6,8 @@
 // pretty-expanded FIXME #23616
 
 #![allow(path_statements)]
-#![feature(box_syntax)]
 
-pub fn main()
-{
-    let y: Box<_> = box 1;
+pub fn main() {
+    let y: Box<_> = Box::new(1);
     y;
 }
index ea3089e747fb539caddfd9b9d1d8868a91353112..7ca53b664ac6cb2057071a047f5fc11093814df8 100644 (file)
@@ -1,12 +1,10 @@
 // run-pass
 // ignore-emscripten no threads support
 
-#![feature(box_syntax)]
-
 use std::thread;
 
 fn f() {
-    let _a: Box<_> = box 0;
+    let _a: Box<_> = Box::new(0);
     panic!();
 }
 
index 76487ef1c14093d604ebe1ba72d7727e7e410ec1..47fbb5bf1c362c4e453b0bf5bc7bbb8586c4ca8b 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(box_syntax)]
-
 use std::fmt;
 
 struct Number {
@@ -22,9 +20,11 @@ fn push(&mut self, n: Box<dyn ToString + 'static>) {
 }
 
 fn main() {
-    let n: Box<_> = box Number { n: 42 };
-    let mut l: Box<_> = box List { list: Vec::new() };
+
+    let n: Box<_> = Number { n: 42 }.into();
+    let mut l: Box<_> = List { list: Vec::new() }.into();
     l.push(n);
+
     let x = n.to_string();
     //~^ ERROR: borrow of moved value: `n`
 }
index b3266562d14b69e1961bda28cafe96cfd85d193f..539ea94a70de54effe3977b6390ba96ae1da869f 100644 (file)
@@ -1,11 +1,12 @@
 error[E0382]: borrow of moved value: `n`
   --> $DIR/use-after-move-implicity-coerced-object.rs:28:13
    |
-LL |     let n: Box<_> = box Number { n: 42 };
+LL |     let n: Box<_> = Number { n: 42 }.into();
    |         - move occurs because `n` has type `Box<Number>`, which does not implement the `Copy` trait
-LL |     let mut l: Box<_> = box List { list: Vec::new() };
+LL |     let mut l: Box<_> = List { list: Vec::new() }.into();
 LL |     l.push(n);
    |            - value moved here
+LL | 
 LL |     let x = n.to_string();
    |             ^ value borrowed here after move
 
index a6f6c45573d0ac80c83875887118535275bfc077..f7a3c0ecce5ba49dc3bd80d03e089959c523d029 100644 (file)
@@ -1,9 +1,9 @@
-#![feature(box_syntax)]
-
 struct S {
     x: Box<isize>,
 }
 
+
+
 impl S {
     pub fn foo(self) -> isize {
         self.bar();
@@ -14,6 +14,6 @@ pub fn bar(self) {}
 }
 
 fn main() {
-    let x = S { x: box 1 };
+    let x = S { x: 1.into() };
     println!("{}", x.foo());
 }
index bb398e5698a8018797877601ccd9596c4f9564f5..2b4b480df0acf81e2b77c2c2ff396c0fa92b782e 100644 (file)
@@ -1,5 +1,5 @@
 // Regression test for #87549.
-// compile-flags: -C incremental=tmp/wf/hir-wf-check-erase-regions
+// incremental
 
 pub struct Table<T, const N: usize>([Option<T>; N]);
 
index 334407c2b2e56d32d773bc105e32ced7a39626df..340acff34f2ab76fd47e23f6a1792a37a95d500b 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "build-manifest"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 toml = "0.5"
index 7d64e20a3d360e95298189fd5e3f0b6d6b702ae5..cf8840ff6ee8918c2f05094be17ac6ea9433dfb9 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "bump-stage0"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
index 9a28ac83c9eb73e42ffafac552c0a55f00dbf40c..0121d66aa2ef5ffa9735f86c2b56f5fdc5a837a6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9a28ac83c9eb73e42ffafac552c0a55f00dbf40c
+Subproject commit 0121d66aa2ef5ffa9735f86c2b56f5fdc5a837a6
index a88272d234456e193af1c3c1d11cd5dc0ac0dc9a..bfd894e2bd27b2f2e57e104bba7c8ab3ee39e194 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "cargotest2"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [[bin]]
 name = "cargotest"
index 1ba241d37761675150a31b80e2e30cc4dc76023e..6bbac6d9a24688598775794ba0f94a991eb1c27c 100644 (file)
@@ -92,7 +92,7 @@ fn check_fn(
                         // be sure we have `self` parameter in this function
                         if let AssocItemKind::Fn { has_self: true } = trait_item.kind {
                             trait_self_ty =
-                                Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty());
+                                Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty().skip_binder());
                         }
                     }
                 }
index 7e4d1b3ef9f0d78365391ada01d0c3e81492024b..f22f52b949e1a8609bb55be59bac866544a02758 100644 (file)
@@ -65,7 +65,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
     }
 }
 
-fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef<'_>]) {
+fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
     use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
     use rustc_hir::{Expr, ExprKind, ImplItemKind, QPath};
 
index e89b2d295b92345f4f1173e0e19911c559cc3bca..8a699f13f2ed267328eeca69fed865048b05225c 100644 (file)
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for use of `.iter().nth()` (and the related
-    /// `.iter_mut().nth()`) on standard library types with O(1) element access.
+    /// `.iter_mut().nth()`) on standard library types with *O*(1) element access.
     ///
     /// ### Why is this bad?
     /// `.get()` and `.get_mut()` are more efficient and more
@@ -2061,7 +2061,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
             then {
                 let first_arg_span = first_arg_ty.span;
                 let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
-                let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
+                let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
                 wrong_self_convention::check(
                     cx,
                     &item.ident.name.as_str(),
@@ -2078,7 +2078,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
             if item.ident.name == sym::new;
             if let TraitItemKind::Fn(_, _) = item.kind;
             let ret_ty = return_ty(cx, item.hir_id());
-            let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
+            let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
             if !contains_ty(cx.tcx, ret_ty, self_ty);
 
             then {
index 05a4a0143195080328d5d06788bb9d1bd75ffdc8..e6c062249994f85c37266b85fc54eb9b0b72f405 100644 (file)
@@ -105,8 +105,7 @@ pub fn hir(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {
             if_else,
         ) = expr.kind
         {
-            let hir = cx.tcx.hir();
-            let mut iter = hir.parent_iter(expr.hir_id);
+            let mut iter = cx.tcx.hir().parent_iter(expr.hir_id);
             if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() {
                 if let Some((
                     _,
@@ -524,28 +523,12 @@ pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
             if let ExpnKind::Macro(_, name) = expr.span.ctxt().outer_expn_data().kind;
             let name = name.as_str();
             if name.ends_with("format_args") || name.ends_with("format_args_nl");
-
-            if let ExprKind::Match(inner_match, [arm], _) = expr.kind;
-
-            // `match match`, if you will
-            if let ExprKind::Match(args, [inner_arm], _) = inner_match.kind;
-            if let ExprKind::Tup(value_args) = args.kind;
-            if let Some(value_args) = value_args
-                .iter()
-                .map(|e| match e.kind {
-                    ExprKind::AddrOf(_, _, e) => Some(e),
-                    _ => None,
-                })
-                .collect();
-            if let ExprKind::Array(args) = inner_arm.body.kind;
-
-            if let ExprKind::Block(Block { stmts: [], expr: Some(expr), .. }, _) = arm.body.kind;
-            if let ExprKind::Call(_, call_args) = expr.kind;
-            if let Some((strs_ref, fmt_expr)) = match call_args {
+            if let ExprKind::Call(_, args) = expr.kind;
+            if let Some((strs_ref, args, fmt_expr)) = match args {
                 // Arguments::new_v1
-                [strs_ref, _] => Some((strs_ref, None)),
+                [strs_ref, args] => Some((strs_ref, args, None)),
                 // Arguments::new_v1_formatted
-                [strs_ref, _, fmt_expr] => Some((strs_ref, Some(fmt_expr))),
+                [strs_ref, args, fmt_expr, _unsafe_arg] => Some((strs_ref, args, Some(fmt_expr))),
                 _ => None,
             };
             if let ExprKind::AddrOf(BorrowKind::Ref, _, strs_arr) = strs_ref.kind;
@@ -561,6 +544,17 @@ pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
                     None
                 })
                 .collect();
+            if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args.kind;
+            if let ExprKind::Match(args, [arm], _) = args.kind;
+            if let ExprKind::Tup(value_args) = args.kind;
+            if let Some(value_args) = value_args
+                .iter()
+                .map(|e| match e.kind {
+                    ExprKind::AddrOf(_, _, e) => Some(e),
+                    _ => None,
+                })
+                .collect();
+            if let ExprKind::Array(args) = arm.body.kind;
             then {
                 Some(FormatArgsExpn {
                     format_string_span: strs_ref.span,
index 3a94f47298390a22ef1fc51459b443691fffc70c..7f5a1bf9c0741707f0e4e34a66cb0fb6a6e199d7 100644 (file)
@@ -833,12 +833,11 @@ fn pat_capture_kind(cx: &LateContext<'_>, pat: &Pat<'_>) -> CaptureKind {
         ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(_), .. }))
     ));
 
-    let map = cx.tcx.hir();
     let mut child_id = e.hir_id;
     let mut capture = CaptureKind::Value;
     let mut capture_expr_ty = e;
 
-    for (parent_id, parent) in map.parent_iter(e.hir_id) {
+    for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) {
         if let [Adjustment {
             kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)),
             target,
@@ -1224,8 +1223,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
 
 /// Gets the loop or closure enclosing the given expression, if any.
 pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
-    let map = tcx.hir();
-    for (_, node) in map.parent_iter(expr.hir_id) {
+    for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
         match node {
             Node::Expr(
                 e
@@ -1244,8 +1242,7 @@ pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Opti
 
 /// Gets the parent node if it's an impl block.
 pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {
-    let map = tcx.hir();
-    match map.parent_iter(id).next() {
+    match tcx.hir().parent_iter(id).next() {
         Some((
             _,
             Node::Item(Item {
@@ -1259,8 +1256,7 @@ pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {
 
 /// Checks if the given expression is the else clause of either an `if` or `if let` expression.
 pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
-    let map = tcx.hir();
-    let mut iter = map.parent_iter(expr.hir_id);
+    let mut iter = tcx.hir().parent_iter(expr.hir_id);
     match iter.next() {
         Some((
             _,
@@ -1794,9 +1790,8 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
 
 /// Gets the node where an expression is either used, or it's type is unified with another branch.
 pub fn get_expr_use_or_unification_node(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<Node<'tcx>> {
-    let map = tcx.hir();
     let mut child_id = expr.hir_id;
-    let mut iter = map.parent_iter(child_id);
+    let mut iter = tcx.hir().parent_iter(child_id);
     loop {
         match iter.next() {
             None => break None,
index e9a9895cb746f39a6abece6de0aa7df4aa26ca92..e2f2e2008bb2604543f1ba4814b0d92538d89fc1 100644 (file)
@@ -194,6 +194,7 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv
         },
         Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => Ok(()),
         Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
+        Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() {
index d6aa3fd2631f5caf1412aa6712b5117569627786..e9426a2d9f58ce6a1ab82baae270a040c4422295 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "compiletest"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 colored = "2"
index 99b0a3454e89ccaed91b758a80c9155d3ed18828..cd0a56d08d8bc6c72d7d5b38db0093f672047652 100644 (file)
@@ -459,3 +459,9 @@ pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<
 pub fn output_base_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
     output_base_dir(config, testpaths, revision).join(testpaths.file.file_stem().unwrap())
 }
+
+/// Absolute path to the directory to use for incremental compilation. Example:
+///   /path/to/build/host-triple/test/ui/relative/testname.mode/testname.inc
+pub fn incremental_dir(config: &Config, testpaths: &TestPaths) -> PathBuf {
+    output_base_name(config, testpaths, None).with_extension("inc")
+}
index 28089e85b55b493dbb3610e91f3f52ab9d930dfe..efd85502799595ab12fc6e31528a3a5510996b88 100644 (file)
@@ -113,6 +113,21 @@ pub struct TestProps {
     // testing harness and used when generating compilation
     // arguments. (In particular, it propagates to the aux-builds.)
     pub incremental_dir: Option<PathBuf>,
+    // If `true`, this test will use incremental compilation.
+    //
+    // This can be set manually with the `incremental` header, or implicitly
+    // by being a part of an incremental mode test. Using the `incremental`
+    // header should be avoided if possible; using an incremental mode test is
+    // preferred. Incremental mode tests support multiple passes, which can
+    // verify that the incremental cache can be loaded properly after being
+    // created. Just setting the header will only verify the behavior with
+    // creating an incremental cache, but doesn't check that it is created
+    // correctly.
+    //
+    // Compiletest will create the incremental directory, and ensure it is
+    // empty before the test starts. Incremental mode tests will reuse the
+    // incremental directory between passes in the same test.
+    pub incremental: bool,
     // How far should the test proceed while still passing.
     pass_mode: Option<PassMode>,
     // Ignore `--pass` overrides from the command line for this test.
@@ -163,6 +178,7 @@ pub fn new() -> Self {
             pretty_compare_only: false,
             forbid_output: vec![],
             incremental_dir: None,
+            incremental: false,
             pass_mode: None,
             fail_mode: None,
             ignore_pass: false,
@@ -350,6 +366,10 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
                 if !self.stderr_per_bitwidth {
                     self.stderr_per_bitwidth = config.parse_stderr_per_bitwidth(ln);
                 }
+
+                if !self.incremental {
+                    self.incremental = config.parse_incremental(ln);
+                }
             });
         }
 
@@ -360,6 +380,10 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
             self.failure_status = 101;
         }
 
+        if config.mode == Mode::Incremental {
+            self.incremental = true;
+        }
+
         for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
             if let Ok(val) = env::var(key) {
                 if self.exec_env.iter().find(|&&(ref x, _)| x == key).is_none() {
@@ -731,6 +755,10 @@ fn parse_rustfix_only_machine_applicable(&self, line: &str) -> bool {
     fn parse_edition(&self, line: &str) -> Option<String> {
         self.parse_name_value_directive(line, "edition")
     }
+
+    fn parse_incremental(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "incremental")
+    }
 }
 
 fn expand_variables(mut value: String, config: &Config) -> String {
index 51a4d74109a639181ee8d1087a7f7e631947728d..2a4bb9eb88b306c666172e0d5b101bd5aba36207 100644 (file)
@@ -1,7 +1,7 @@
 // ignore-tidy-filelength
 
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
-use crate::common::{output_base_dir, output_base_name, output_testname_unique};
+use crate::common::{incremental_dir, output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui};
 use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
 use crate::common::{CompareMode, FailMode, PassMode};
@@ -229,18 +229,24 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
         print!("\n\n");
     }
     debug!("running {:?}", testpaths.file.display());
-    let props = TestProps::from_file(&testpaths.file, revision, &config);
+    let mut props = TestProps::from_file(&testpaths.file, revision, &config);
+    if props.incremental {
+        props.incremental_dir = Some(incremental_dir(&config, testpaths));
+    }
 
     let cx = TestCx { config: &config, props: &props, testpaths, revision };
     create_dir_all(&cx.output_base_dir()).unwrap();
+    if props.incremental {
+        cx.init_incremental_test();
+    }
 
     if config.mode == Incremental {
         // Incremental tests are special because they cannot be run in
         // parallel.
         assert!(!props.revisions.is_empty(), "Incremental tests require revisions.");
-        cx.init_incremental_test();
         for revision in &props.revisions {
-            let revision_props = TestProps::from_file(&testpaths.file, Some(revision), &config);
+            let mut revision_props = TestProps::from_file(&testpaths.file, Some(revision), &config);
+            revision_props.incremental_dir = props.incremental_dir.clone();
             let rev_cx = TestCx {
                 config: &config,
                 props: &revision_props,
@@ -2937,7 +2943,7 @@ fn init_incremental_test(&self) {
         // incremental workproduct directory.  Delete any old
         // incremental work products that may be there from prior
         // runs.
-        let incremental_dir = self.incremental_dir();
+        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
         if incremental_dir.exists() {
             // Canonicalizing the path will convert it to the //?/ format
             // on Windows, which enables paths longer than 260 character
@@ -2947,7 +2953,7 @@ fn init_incremental_test(&self) {
         fs::create_dir_all(&incremental_dir).unwrap();
 
         if self.config.verbose {
-            print!("init_incremental_test: incremental_dir={}", incremental_dir.display());
+            println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
         }
     }
 
@@ -2974,46 +2980,30 @@ fn run_incremental_test(&self) {
         let revision = self.revision.expect("incremental tests require a list of revisions");
 
         // Incremental workproduct directory should have already been created.
-        let incremental_dir = self.incremental_dir();
+        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
         assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
 
-        // Add an extra flag pointing at the incremental directory.
-        let mut revision_props = self.props.clone();
-        revision_props.incremental_dir = Some(incremental_dir);
-
-        let revision_cx = TestCx {
-            config: self.config,
-            props: &revision_props,
-            testpaths: self.testpaths,
-            revision: self.revision,
-        };
-
         if self.config.verbose {
-            print!("revision={:?} revision_props={:#?}", revision, revision_props);
+            print!("revision={:?} props={:#?}", revision, self.props);
         }
 
         if revision.starts_with("rpass") {
-            if revision_cx.props.should_ice {
-                revision_cx.fatal("can only use should-ice in cfail tests");
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
             }
-            revision_cx.run_rpass_test();
+            self.run_rpass_test();
         } else if revision.starts_with("rfail") {
-            if revision_cx.props.should_ice {
-                revision_cx.fatal("can only use should-ice in cfail tests");
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
             }
-            revision_cx.run_rfail_test();
+            self.run_rfail_test();
         } else if revision.starts_with("cfail") {
-            revision_cx.run_cfail_test();
+            self.run_cfail_test();
         } else {
-            revision_cx.fatal("revision name must begin with rpass, rfail, or cfail");
+            self.fatal("revision name must begin with rpass, rfail, or cfail");
         }
     }
 
-    /// Directory where incremental work products are stored.
-    fn incremental_dir(&self) -> PathBuf {
-        self.output_base_name().with_extension("inc")
-    }
-
     fn run_rmake_test(&self) {
         let cwd = env::current_dir().unwrap();
         let src_root = self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
index 75d392951eca77e9fe73a16fa58d6c0e0798d24a..d03c21dc5086fe499e14d94d00e366669467955a 100644 (file)
@@ -96,7 +96,8 @@
 ];
 
 pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[
-    "aarch64-apple-darwin",
+    // FIXME: currently broken, see #88132
+    // "aarch64-apple-darwin",
     "aarch64-unknown-linux-gnu",
     "x86_64-apple-darwin",
     "x86_64-unknown-linux-gnu",
index 2e4b7beb3760154857a6441c1c9f86b780b199d1..c84b79e11e9b4ddb578f3653f31d21e660a27709 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "error_index_generator"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 rustdoc = { path = "../../librustdoc" }
index 358dff0653292ea487261e019dcd394fb259ac31..9a25b6c1f1c87e2eb77e90f64074bc8c00060825 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "expand-yaml-anchors"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 yaml-rust = "0.4.3"
index e88d2f0d928fb4c153b3cecaf7bf11ef05237991..34d3954db28dc6b5b1836889db6a35cc30c1fd16 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "html-checker"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [[bin]]
 name = "html-checker"
index a65deb1254168562eca1d32142c25549efa30c6a..ccabe6483d7a41cd4941949dc09e564edc5b4db9 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "jsondocck"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 jsonpath_lib = "0.2"
index 21ba22695564654cb6ff92f1b5a5b7f213e56b80..1d8f2f918823fc01876a2e559f1b59be8e7edb83 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "linkchecker"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [[bin]]
 name = "linkchecker"
index 6792887fa5d718f31ec265ae53b4c495d0920a8a..3578bda8276e76e2dfe3ea4d2d7e0a07394acfb0 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "lint-docs"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 description = "A script to extract the lint documentation for the rustc book."
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
index e5c7f1257123801d48a39812cfb003967342ee6d..fdc89a184da527ba7bb44fc28b552eb1390a46ce 100644 (file)
@@ -149,6 +149,10 @@ fn lints_from_file(&self, path: &Path) -> Result<Vec<Lint>, Box<dyn Error>> {
                         } else if line.starts_with("// ") {
                             // Ignore comments.
                             continue;
+                        } else if line.starts_with("#[allow") {
+                            // Ignore allow of lints (useful for
+                            // invalid_rust_codeblocks).
+                            continue;
                         } else {
                             let name = lint_name(line).map_err(|e| {
                                 format!(
index 7b20ba83546be38031e61c062f479e94e058c9fd..d59cd6b3d8e225834c3444d91ed29a277bf62bb4 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "remote-test-client"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
index 01309aec9a33895ec50d663dec2db95fdfd4ef9d..e6be8530cf635ad18f23b026a32846755a42f123 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "remote-test-server"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
index b73b321478d3b2a98d380eb79de717e01620c4e9..f1d7f98ed07b9934286b9c4809dd4d7a47537879 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b73b321478d3b2a98d380eb79de717e01620c4e9
+Subproject commit f1d7f98ed07b9934286b9c4809dd4d7a47537879
index 157409bc8472c80200debddf3eb61f82bba9c8e9..2bb73b3262d8d7bde3509446893af75f20c3d938 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rust-demangler"
 version = "0.0.1"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 regex = "1.0"
index da36ce0e69002442d5bafd6c910af73770bfad8f..de1327d74ff57f8d567b9dac4259dca434d52f57 100644 (file)
@@ -2,7 +2,7 @@
 name = "rustbook"
 version = "0.1.0"
 license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 clap = "2.25.0"
index 38b9fefbaf576ee11205af5e92eea6a6dd73b692..a28cf28841e54de042dba7cf874af3983bb01fbb 100644 (file)
@@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
 """
-edition = "2018"
+edition = "2021"
 
 [lib]
 path = "lib.rs"
index 4b2ad982a84fb2d81b2bce8f34e030e5d0cae24f..3d8c77d36d70dd965fcb5419aa2c08e4defe1624 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc-themes"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 [[bin]]
 name = "rustdoc-themes"
index 5625707b25a5323d82726e3019b1c9fb3faacc54..c4101f72cc2da64fe6faf3a17298f1e1806d091a 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc-tool"
 version = "0.0.0"
-edition = "2018"
+edition = "2021"
 
 # Cargo adds a number of paths to the dylib search path on windows, which results in
 # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
index 81e3e26e8b000db67ace239c2e45fd475d1d727d..7b4667c17c8647cd3e6f7ddacf33a077df20b531 100644 (file)
@@ -8,7 +8,7 @@ readme = "README.md"
 license = "Apache-2.0/MIT"
 build = "build.rs"
 categories = ["development-tools"]
-edition = "2018"
+edition = "2021"
 
 [[bin]]
 name = "rustfmt"
index 57fe5a62e9aa7a629411344b958337f877ae8e07..69c8063f42e26693c441251b65210961d50feb88 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "tidy"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 autobins = false
 
 [dependencies]
index 283c43e325c05422c7003f069005b025d97ad2ab..b5e9ceddbafd166832874a26c34009ae1b363f60 100644 (file)
@@ -1,10 +1,15 @@
-//! Tidy check to ensure that crate `edition` is '2018'
+//! Tidy check to ensure that crate `edition` is '2018' or '2021'.
 
 use std::path::Path;
 
 fn is_edition_2018(mut line: &str) -> bool {
     line = line.trim();
-    line == "edition = \"2018\"" || line == "edition = \'2018\'"
+    line == "edition = \"2018\""
+}
+
+fn is_edition_2021(mut line: &str) -> bool {
+    line = line.trim();
+    line == "edition = \"2021\""
 }
 
 pub fn check(path: &Path, bad: &mut bool) {
@@ -13,17 +18,38 @@ pub fn check(path: &Path, bad: &mut bool) {
         &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
         &mut |entry, contents| {
             let file = entry.path();
+            let filestr = file.to_string_lossy().replace("\\", "/");
             let filename = file.file_name().unwrap();
             if filename != "Cargo.toml" {
                 return;
             }
-            let has_edition = contents.lines().any(is_edition_2018);
-            if !has_edition {
-                tidy_error!(
-                    bad,
-                    "{} doesn't have `edition = \"2018\"` on a separate line",
-                    file.display()
-                );
+
+            // Library crates are not yet ready to migrate to 2021.
+            //
+            // The reference and rustc-dev-guide are submodules, so are left at
+            // 2018 for now. They should be removed from this exception list
+            // when bumped.
+            if path.components().any(|c| c.as_os_str() == "library")
+                || filestr.contains("src/doc/reference/style-check/Cargo.toml")
+                || filestr.contains("src/doc/rustc-dev-guide/ci/date-check/Cargo.toml")
+            {
+                let has = contents.lines().any(is_edition_2018);
+                if !has {
+                    tidy_error!(
+                        bad,
+                        "{} doesn't have `edition = \"2018\"` on a separate line",
+                        file.display()
+                    );
+                }
+            } else {
+                let is_2021 = contents.lines().any(is_edition_2021);
+                if !is_2021 {
+                    tidy_error!(
+                        bad,
+                        "{} doesn't have `edition = \"2021\"` on a separate line",
+                        file.display()
+                    );
+                }
             }
         },
     );
index d6119cac5f39eb46d314e3a5c2ad787e8ee861ca..3f08165a3fc63350077d0c234a00bb07a4bcd51f 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "tier-check"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 license = "MIT OR Apache-2.0"
 
 [dependencies]
index 948773f7810c3d2c85f560538124cf35f33012b6..ef01877c0b94bcffff9e49148aa7be1a00c84ac8 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "unicode-bdd"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
index febeaa446b39411e574dc80868e166177f706ee1..73e5a91bec70a358917ff9ddf99e4c21de25cc3c 100644 (file)
@@ -2,7 +2,7 @@
 name = "unstable-book-gen"
 version = "0.1.0"
 license = "MIT OR Apache-2.0"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 tidy = { path = "../tidy" }
index 264a741159a8acb7a475eb382ba41ba76f864029..315027279623411f8af85ed53c86550c79556d70 100644 (file)
@@ -2,5 +2,5 @@
 name = "x"
 version = "0.1.0"
 description = "Run x.py slightly more conveniently"
-edition = "2018"
+edition = "2021"
 publish = false