]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #82183 - michaelwoerister:lazier-defpathhash-loading2, r=wesleywiser
authorbors <bors@rust-lang.org>
Sat, 18 Sep 2021 14:37:39 +0000 (14:37 +0000)
committerbors <bors@rust-lang.org>
Sat, 18 Sep 2021 14:37:39 +0000 (14:37 +0000)
Simplify lazy DefPathHash decoding by using an on-disk hash table.

This PR simplifies the logic around mapping `DefPathHash` values encountered during incremental compilation to valid `DefId`s in the current session. It is able to do so by using an on-disk hash table encoding that allows for looking up values directly, i.e. without deserializing the entire table.

The main simplification comes from not having to keep track of `DefPathHashes` being used during the compilation session.

449 files changed:
Cargo.lock
compiler/rustc_ast/src/ast.rs
compiler/rustc_ast/src/mut_visit.rs
compiler/rustc_ast/src/visit.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_passes/src/ast_validation.rs
compiler/rustc_ast_passes/src/feature_gate.rs
compiler/rustc_ast_pretty/src/pprust/state.rs
compiler/rustc_borrowck/src/consumers.rs
compiler/rustc_borrowck/src/diagnostics/move_errors.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/nll.rs
compiler/rustc_borrowck/src/region_infer/opaque_types.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_builtin_macros/src/deriving/debug.rs
compiler/rustc_codegen_llvm/Cargo.toml
compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
compiler/rustc_codegen_ssa/src/back/link.rs
compiler/rustc_codegen_ssa/src/back/linker.rs
compiler/rustc_const_eval/src/const_eval/eval_queries.rs
compiler/rustc_const_eval/src/const_eval/fn_queries.rs
compiler/rustc_const_eval/src/const_eval/machine.rs
compiler/rustc_const_eval/src/interpret/intrinsics.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/check_consts/mod.rs
compiler/rustc_const_eval/src/transform/check_consts/ops.rs
compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
compiler/rustc_const_eval/src/transform/promote_consts.rs
compiler/rustc_driver/src/lib.rs
compiler/rustc_error_codes/src/error_codes/E0071.md
compiler/rustc_errors/src/diagnostic.rs
compiler/rustc_expand/src/mbe/quoted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_hir/src/lang_items.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
compiler/rustc_infer/src/traits/error_reporting/mod.rs
compiler/rustc_infer/src/traits/mod.rs
compiler/rustc_infer/src/traits/project.rs
compiler/rustc_interface/src/tests.rs
compiler/rustc_lint/src/traits.rs
compiler/rustc_lint/src/types.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
compiler/rustc_macros/src/symbols.rs
compiler/rustc_middle/src/mir/interpret/pointer.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/traits/select.rs
compiler/rustc_middle/src/traits/structural_impls.rs
compiler/rustc_middle/src/ty/adt.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/util.rs
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_dataflow/src/lib.rs
compiler/rustc_mir_transform/src/lib.rs
compiler/rustc_mir_transform/src/remove_zsts.rs
compiler/rustc_monomorphize/src/polymorphize.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/parser/stmt.rs
compiler/rustc_parse/src/parser/ty.rs
compiler/rustc_passes/src/stability.rs
compiler/rustc_query_system/src/dep_graph/serialized.rs
compiler/rustc_resolve/src/late/lifetimes.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/filesearch.rs
compiler/rustc_session/src/options.rs
compiler/rustc_session/src/search_paths.rs
compiler/rustc_session/src/session.rs
compiler/rustc_span/src/lib.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_span/src/symbol/tests.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/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_ty_utils/src/instance.rs
compiler/rustc_ty_utils/src/needs_drop.rs
compiler/rustc_typeck/src/check/callee.rs
compiler/rustc_typeck/src/check/coercion.rs
compiler/rustc_typeck/src/check/expr.rs
compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
compiler/rustc_typeck/src/check/pat.rs
compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
library/alloc/src/borrow.rs
library/backtrace
library/core/src/cell.rs
library/core/src/iter/traits/iterator.rs
library/core/src/mem/manually_drop.rs
library/core/src/num/wrapping.rs
library/core/src/ops/deref.rs
library/core/src/panic.rs
library/core/src/panicking.rs
library/std/src/ffi/c_str.rs
library/std/src/keyword_docs.rs
library/std/src/lib.rs
library/std/src/net/tcp.rs
library/std/src/os/mod.rs
library/std/src/os/unix/fs.rs
library/std/src/panic.rs
library/std/src/rt.rs
library/std/src/sys/unix/fs.rs
src/bootstrap/doc.rs
src/bootstrap/test.rs
src/doc/embedded-book
src/doc/rust-by-example
src/doc/rustc-dev-guide
src/doc/rustdoc/src/unstable-features.md
src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md [new file with mode: 0644]
src/doc/unstable-book/src/library-features/asm.md
src/librustdoc/config.rs
src/librustdoc/core.rs
src/librustdoc/docfs.rs
src/librustdoc/doctest.rs
src/librustdoc/doctest/tests.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/span_map.rs
src/librustdoc/html/render/write_shared.rs
src/librustdoc/html/sources.rs
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/html/static/css/themes/ayu.css
src/librustdoc/html/static/css/themes/dark.css
src/librustdoc/html/static/css/themes/light.css
src/librustdoc/html/static/js/main.js
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/passes/doc_test_lints.rs
src/test/debuginfo/mutex.rs
src/test/pretty/anonymous-types.rs [deleted file]
src/test/run-make-fulldeps/reproducible-build/Makefile
src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
src/test/rustdoc-gui/code-sidebar-toggle.goml
src/test/rustdoc-gui/jump-to-def-background.goml [new file with mode: 0644]
src/test/rustdoc-gui/src/link_to_definition/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/link_to_definition/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/link_to_definition/lib.rs [new file with mode: 0644]
src/test/rustdoc-ui/display-output.rs [new file with mode: 0644]
src/test/rustdoc-ui/display-output.stdout [new file with mode: 0644]
src/test/rustdoc-ui/lint-missing-doc-code-example.rs
src/test/rustdoc/check-source-code-urls-to-def-std.rs [new file with mode: 0644]
src/test/rustdoc/check-source-code-urls-to-def.rs
src/test/ui/associated-consts/associated-const-in-trait.stderr
src/test/ui/associated-item/issue-48027.stderr
src/test/ui/associated-types/associated-types-bound-failure.stderr
src/test/ui/associated-types/associated-types-path-2.rs
src/test/ui/associated-types/associated-types-path-2.stderr
src/test/ui/associated-types/issue-19883.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-19883.stderr [new file with mode: 0644]
src/test/ui/associated-types/issue-21363.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
src/test/ui/async-await/auxiliary/issue-72470-lib.rs [new file with mode: 0644]
src/test/ui/async-await/issue-72442.stderr
src/test/ui/async-await/issue-72470-llvm-dominate.rs [new file with mode: 0644]
src/test/ui/auxiliary/define-macro.rs [deleted file]
src/test/ui/auxiliary/issue-72470-lib.rs [deleted file]
src/test/ui/borrowck/borrowck-in-static.stderr
src/test/ui/borrowck/borrowck-move-by-capture.stderr
src/test/ui/borrowck/issue-87456-point-to-closure.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-87456-point-to-closure.stderr [new file with mode: 0644]
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
src/test/ui/box/into-boxed-slice-fail.stderr
src/test/ui/bug-7183-generics.rs [deleted file]
src/test/ui/chalkify/type_inference.stderr
src/test/ui/closure-expected.stderr
src/test/ui/closures/closure-bounds-subtype.stderr
src/test/ui/closures/coerce-unsafe-to-closure.stderr
src/test/ui/closures/issue-78720.rs [new file with mode: 0644]
src/test/ui/closures/issue-78720.stderr [new file with mode: 0644]
src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr
src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
src/test/ui/const-generics/issues/issue-86530.stderr
src/test/ui/const-generics/issues/issue-87493.rs [new file with mode: 0644]
src/test/ui/const-generics/issues/issue-87493.stderr [new file with mode: 0644]
src/test/ui/consts/const-eval/const_panic.rs
src/test/ui/consts/const-eval/const_panic.stderr
src/test/ui/consts/const-eval/const_panic_2021.rs
src/test/ui/consts/const-eval/const_panic_2021.stderr
src/test/ui/consts/issue-23833.rs [new file with mode: 0644]
src/test/ui/consts/issue-34784.rs [new file with mode: 0644]
src/test/ui/consts/min_const_fn/min_const_fn.stderr
src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
src/test/ui/derives/deriving-copyclone.stderr
src/test/ui/deriving/issue-3935.rs [new file with mode: 0644]
src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
src/test/ui/enable-unstable-lib-feature.rs [deleted file]
src/test/ui/enable-unstable-lib-feature.stderr [deleted file]
src/test/ui/error-codes/E0038.stderr
src/test/ui/error-codes/E0277.stderr
src/test/ui/error-should-say-copy-not-pod.stderr
src/test/ui/expr-empty-ret.rs [deleted file]
src/test/ui/expr/malformed_closure/ruby_style_closure.stderr
src/test/ui/extern/extern-wrong-value-type.stderr
src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
src/test/ui/feature-gates/feature-gate-unnamed_fields.rs [deleted file]
src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr
src/test/ui/fn/fn-trait-formatting.stderr
src/test/ui/generator/issue-88653.rs [new file with mode: 0644]
src/test/ui/generator/issue-88653.stderr [new file with mode: 0644]
src/test/ui/generator/static-not-unpin.stderr
src/test/ui/generic-associated-types/gat-in-trait-path.stderr
src/test/ui/generic-associated-types/issue-67510-pass.stderr
src/test/ui/generic-associated-types/issue-76535.stderr
src/test/ui/generic-associated-types/issue-78671.stderr
src/test/ui/generic-associated-types/issue-79422.stderr
src/test/ui/generic-associated-types/trait-objects.stderr
src/test/ui/generics/mid-path-type-params.rs [new file with mode: 0644]
src/test/ui/guards.rs [deleted file]
src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr
src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.rs [new file with mode: 0644]
src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.stderr [new file with mode: 0644]
src/test/ui/inference/issue-71309.rs [new file with mode: 0644]
src/test/ui/inference/issue-71309.stderr [new file with mode: 0644]
src/test/ui/issue-72470-llvm-dominate.rs [deleted file]
src/test/ui/issues/issue-17651.rs
src/test/ui/issues/issue-17651.stderr
src/test/ui/issues/issue-18959.stderr
src/test/ui/issues/issue-19538.stderr
src/test/ui/issues/issue-19883.rs [deleted file]
src/test/ui/issues/issue-19883.stderr [deleted file]
src/test/ui/issues/issue-20692.rs [deleted file]
src/test/ui/issues/issue-20692.stderr [deleted file]
src/test/ui/issues/issue-21363.rs [deleted file]
src/test/ui/issues/issue-23825.rs [deleted file]
src/test/ui/issues/issue-23833.rs [deleted file]
src/test/ui/issues/issue-23966.stderr
src/test/ui/issues/issue-25076.stderr
src/test/ui/issues/issue-28098.stderr
src/test/ui/issues/issue-30355.stderr
src/test/ui/issues/issue-33498.rs [deleted file]
src/test/ui/issues/issue-34194.rs [deleted file]
src/test/ui/issues/issue-34255-1.rs
src/test/ui/issues/issue-34255-1.stderr
src/test/ui/issues/issue-34784.rs [deleted file]
src/test/ui/issues/issue-35376.rs [deleted file]
src/test/ui/issues/issue-35376.stderr [deleted file]
src/test/ui/issues/issue-36768.rs [deleted file]
src/test/ui/issues/issue-37433.rs [deleted file]
src/test/ui/issues/issue-37433.stderr [deleted file]
src/test/ui/issues/issue-38002.rs [deleted file]
src/test/ui/issues/issue-3935.rs [deleted file]
src/test/ui/issues/issue-41255.rs [deleted file]
src/test/ui/issues/issue-41255.stderr [deleted file]
src/test/ui/issues/issue-42944.rs [deleted file]
src/test/ui/issues/issue-42944.stderr [deleted file]
src/test/ui/issues/issue-4335.stderr
src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.mir.stderr [deleted file]
src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs [deleted file]
src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.thir.stderr [deleted file]
src/test/ui/issues/issue-47706-trait.stderr
src/test/ui/issues/issue-47706.stderr
src/test/ui/issues/issue-51632-try-desugar-incompatible-types.rs
src/test/ui/issues/issue-51632-try-desugar-incompatible-types.stderr
src/test/ui/issues/issue-53912.rs [deleted file]
src/test/ui/issues/issue-56031.stderr
src/test/ui/issues/issue-56685.rs [deleted file]
src/test/ui/issues/issue-56685.stderr [deleted file]
src/test/ui/issues/issue-57410.rs [deleted file]
src/test/ui/issues/issue-5791.rs [deleted file]
src/test/ui/issues/issue-5791.stderr [deleted file]
src/test/ui/issues/issue-59494.stderr
src/test/ui/issues/issue-60218.stderr
src/test/ui/issues/issue-60283.stderr
src/test/ui/issues/issue-66353.stderr
src/test/ui/issues/issue-74614.rs [deleted file]
src/test/ui/issues/issue-78720.rs [deleted file]
src/test/ui/issues/issue-78720.stderr [deleted file]
src/test/ui/issues/issue-79593.rs [deleted file]
src/test/ui/issues/issue-79593.stderr [deleted file]
src/test/ui/issues/issue-79744.rs [deleted file]
src/test/ui/issues/issue-79744.stderr [deleted file]
src/test/ui/issues/issue-87199.stderr
src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs [deleted file]
src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr [deleted file]
src/test/ui/kindck/kindck-impl-type-params-2.stderr
src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
src/test/ui/lifetimes/issue-77175.rs [new file with mode: 0644]
src/test/ui/lint/enable-unstable-lib-feature.rs [new file with mode: 0644]
src/test/ui/lint/enable-unstable-lib-feature.stderr [new file with mode: 0644]
src/test/ui/lint/issue-57410.rs [new file with mode: 0644]
src/test/ui/lint/issue-79744.rs [new file with mode: 0644]
src/test/ui/lint/issue-79744.stderr [new file with mode: 0644]
src/test/ui/llvm-asm/issue-37433.rs [new file with mode: 0644]
src/test/ui/llvm-asm/issue-37433.stderr [new file with mode: 0644]
src/test/ui/macros/auxiliary/define-macro.rs [new file with mode: 0644]
src/test/ui/macros/out-of-order-shadowing.rs [new file with mode: 0644]
src/test/ui/macros/out-of-order-shadowing.stderr [new file with mode: 0644]
src/test/ui/match/guards.rs [new file with mode: 0644]
src/test/ui/match/issue-33498.rs [new file with mode: 0644]
src/test/ui/match/issue-41255.rs [new file with mode: 0644]
src/test/ui/match/issue-41255.stderr [new file with mode: 0644]
src/test/ui/match/issue-56685.rs [new file with mode: 0644]
src/test/ui/match/issue-56685.stderr [new file with mode: 0644]
src/test/ui/mid-path-type-params.rs [deleted file]
src/test/ui/mir/remove-zsts-query-cycle.rs [new file with mode: 0644]
src/test/ui/mismatched_types/E0631.stderr
src/test/ui/mismatched_types/closure-arg-count.stderr
src/test/ui/mismatched_types/fn-variance-1.stderr
src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
src/test/ui/mutexguard-sync.stderr
src/test/ui/namespace/namespace-mix.stderr
src/test/ui/never_type/expr-empty-ret.rs [new file with mode: 0644]
src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
src/test/ui/no_send-rc.stderr
src/test/ui/no_send-struct.stderr
src/test/ui/no_share-struct.stderr
src/test/ui/object-does-not-impl-trait.stderr
src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
src/test/ui/object-safety/object-safety-generics.curr.stderr
src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
src/test/ui/on-unimplemented/enclosing-scope.stderr
src/test/ui/on-unimplemented/multiple-impls.stderr
src/test/ui/on-unimplemented/on-impl.stderr
src/test/ui/out-of-order-shadowing.rs [deleted file]
src/test/ui/out-of-order-shadowing.stderr [deleted file]
src/test/ui/parser/issue-44406.rs
src/test/ui/parser/issue-44406.stderr
src/test/ui/parser/issue-88583-union-as-ident.rs [new file with mode: 0644]
src/test/ui/parser/issue-88818.rs [new file with mode: 0644]
src/test/ui/parser/issue-88818.stderr [new file with mode: 0644]
src/test/ui/parser/macro-braces-dot-question.rs [new file with mode: 0644]
src/test/ui/parser/recover-for-loop-parens-around-head.rs
src/test/ui/parser/recover-for-loop-parens-around-head.stderr
src/test/ui/parser/recover-from-bad-variant.rs
src/test/ui/parser/recover-from-bad-variant.stderr
src/test/ui/phantom-auto-trait.stderr
src/test/ui/polymorphization/issue-74614.rs [new file with mode: 0644]
src/test/ui/privacy/issue-79593.rs [new file with mode: 0644]
src/test/ui/privacy/issue-79593.stderr [new file with mode: 0644]
src/test/ui/repr/repr-transparent-issue-87496.rs [new file with mode: 0644]
src/test/ui/repr/repr-transparent-issue-87496.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-42944.rs [new file with mode: 0644]
src/test/ui/resolve/issue-42944.stderr [new file with mode: 0644]
src/test/ui/resolve/use-self-in-inner-fn.rs [new file with mode: 0644]
src/test/ui/resolve/use-self-in-inner-fn.stderr [new file with mode: 0644]
src/test/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs
src/test/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs
src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs [new file with mode: 0644]
src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr [new file with mode: 0644]
src/test/ui/rfc-2008-non-exhaustive/struct.stderr
src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/const-drop.rs [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs [new file with mode: 0644]
src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
src/test/ui/specialization/issue-35376.rs [new file with mode: 0644]
src/test/ui/specialization/issue-35376.stderr [new file with mode: 0644]
src/test/ui/static/issue-34194.rs [new file with mode: 0644]
src/test/ui/str/str-idx.stderr
src/test/ui/str/str-mut-idx.stderr
src/test/ui/structs-enums/issue-38002.rs [new file with mode: 0644]
src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
src/test/ui/suggestions/imm-ref-trait-object-literal.stderr
src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr
src/test/ui/suggestions/issue-62843.stderr
src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
src/test/ui/suggestions/issue-84973-2.stderr
src/test/ui/suggestions/issue-84973-blacklist.rs
src/test/ui/suggestions/issue-84973-blacklist.stderr
src/test/ui/suggestions/issue-84973-negative.stderr
src/test/ui/suggestions/issue-84973.stderr
src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr
src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
src/test/ui/suggestions/option-content-move2.stderr
src/test/ui/suggestions/restrict-type-argument.stderr
src/test/ui/suggestions/suggest-change-mut.stderr
src/test/ui/symbol-names/issue-53912.rs [new file with mode: 0644]
src/test/ui/test-attrs/issue-36768.rs [new file with mode: 0644]
src/test/ui/thread-local/tls.rs [new file with mode: 0644]
src/test/ui/tls.rs [deleted file]
src/test/ui/traits/bound/same-crate-name.stderr
src/test/ui/traits/bug-7183-generics.rs [new file with mode: 0644]
src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
src/test/ui/traits/issue-20692.rs [new file with mode: 0644]
src/test/ui/traits/issue-20692.stderr [new file with mode: 0644]
src/test/ui/traits/issue-23825.rs [new file with mode: 0644]
src/test/ui/traits/item-privacy.stderr
src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
src/test/ui/traits/reservation-impl/no-use.stderr
src/test/ui/traits/suggest-deferences/issue-39029.stderr
src/test/ui/traits/suggest-deferences/issue-62530.stderr
src/test/ui/traits/suggest-deferences/multiple-0.stderr
src/test/ui/traits/suggest-deferences/multiple-1.stderr
src/test/ui/traits/test-2.stderr
src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
src/test/ui/typeck/issue-88803-call-expr-method.fixed [new file with mode: 0644]
src/test/ui/typeck/issue-88803-call-expr-method.rs [new file with mode: 0644]
src/test/ui/typeck/issue-88803-call-expr-method.stderr [new file with mode: 0644]
src/test/ui/typeck/issue-88844.rs [new file with mode: 0644]
src/test/ui/typeck/issue-88844.stderr [new file with mode: 0644]
src/test/ui/typeck/typeck-unsafe-always-share.stderr
src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
src/test/ui/unnamed_fields/restrict_anonymous.rs [deleted file]
src/test/ui/unnamed_fields/restrict_anonymous.stderr [deleted file]
src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr [new file with mode: 0644]
src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs [new file with mode: 0644]
src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr [new file with mode: 0644]
src/test/ui/unsized-locals/unsized-exprs.stderr
src/test/ui/unsized/unsized3.rs
src/test/ui/unsized/unsized3.stderr
src/test/ui/use-self-in-inner-fn.rs [deleted file]
src/test/ui/use-self-in-inner-fn.stderr [deleted file]
src/test/ui/vtable-res-trait-param.stderr
src/test/ui/wf/issue-87495.stderr
src/test/ui/wf/wf-object-safe.stderr
src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
src/tools/cargo
src/tools/clippy/clippy_utils/src/paths.rs
src/tools/publish_toolstate.py
src/tools/rustfmt/src/items.rs
src/tools/rustfmt/src/lib.rs
src/tools/rustfmt/src/types.rs
src/tools/tidy/src/ui_tests.rs

index e3c5340af358ad7ffffe0b9f933084120e96b43d..35eac402190d9c811278dae7efbce2e264f1ce63 100644 (file)
@@ -267,7 +267,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
 
 [[package]]
 name = "cargo"
-version = "0.57.0"
+version = "0.58.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -882,9 +882,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.45+curl-7.78.0"
+version = "0.4.47+curl-7.79.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb"
+checksum = "1ab94a47d9b61f2d905beb7a3d46aba7704c9f1dfcf84e7d178998d9e95f7989"
 dependencies = [
  "cc",
  "libc",
@@ -3663,6 +3663,7 @@ dependencies = [
  "libc",
  "measureme",
  "rustc-demangle",
+ "rustc_arena",
  "rustc_ast",
  "rustc_attr",
  "rustc_codegen_ssa",
index b92c5fa072786331b9c57d2eff79243c43fb67c2..c27ab810a4c608f0e1cefc98c4881577b269f887 100644 (file)
@@ -1902,10 +1902,6 @@ pub enum TyKind {
     Never,
     /// A tuple (`(A, B, C, D,...)`).
     Tup(Vec<P<Ty>>),
-    /// An anonymous struct type i.e. `struct { foo: Type }`
-    AnonymousStruct(Vec<FieldDef>, bool),
-    /// An anonymous union type i.e. `union { bar: Type }`
-    AnonymousUnion(Vec<FieldDef>, bool),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
index 2ec941cbb2466a95af61f5cb82254c7a1a0f4324..ba86036577ac5c1f5efb12102a19b13d783159f5 100644 (file)
@@ -484,9 +484,6 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             visit_vec(bounds, |bound| vis.visit_param_bound(bound));
         }
         TyKind::MacCall(mac) => vis.visit_mac_call(mac),
-        TyKind::AnonymousStruct(fields, ..) | TyKind::AnonymousUnion(fields, ..) => {
-            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
-        }
     }
     vis.visit_span(span);
     visit_lazy_tts(tokens, vis);
index c30f711b3970793fdde4b52ec1c3adc40740aefa..b38031042e0f09ed1265acf60725eca661dc84f5 100644 (file)
@@ -407,9 +407,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
         TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
         TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
         TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
-        TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => {
-            walk_list!(visitor, visit_field_def, fields)
-        }
         TyKind::Never | TyKind::CVarArgs => {}
     }
 }
index b7497c713f3df32d76a8f04ce0e6e98b0a4720c4..a77e3e1997fd67555b0eef0e892e00df8cc5d9e8 100644 (file)
@@ -748,10 +748,7 @@ fn lower_variant_data(
         }
     }
 
-    pub(super) fn lower_field_def(
-        &mut self,
-        (index, f): (usize, &FieldDef),
-    ) -> hir::FieldDef<'hir> {
+    fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
         let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
             let t = self.lower_path_ty(
                 &f.ty,
index 8d731d7a57895fa2a448de1f0b71e6c3636598a0..4cf54b07dbef88b67fafb5cebe53a1548a8942fb 100644 (file)
@@ -1301,15 +1301,6 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) ->
         let kind = match t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => hir::TyKind::Err,
-            // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
-            TyKind::AnonymousStruct(ref _fields, _recovered) => {
-                self.sess.struct_span_err(t.span, "anonymous structs are unimplemented").emit();
-                hir::TyKind::Err
-            }
-            TyKind::AnonymousUnion(ref _fields, _recovered) => {
-                self.sess.struct_span_err(t.span, "anonymous unions are unimplemented").emit();
-                hir::TyKind::Err
-            }
             TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Rptr(ref region, ref mt) => {
index e9dce953c73888e3e80ea8258117bc3ac7a81878..24108f779c818529b674b0f1e42f91d032d99909 100644 (file)
@@ -193,11 +193,6 @@ fn walk_ty(&mut self, t: &'a Ty) {
                     }
                 }
             }
-            TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => {
-                self.with_banned_assoc_ty_bound(|this| {
-                    walk_list!(this, visit_struct_field_def, fields)
-                });
-            }
             _ => visit::walk_ty(self, t),
         }
     }
@@ -205,7 +200,6 @@ fn walk_ty(&mut self, t: &'a Ty) {
     fn visit_struct_field_def(&mut self, field: &'a FieldDef) {
         if let Some(ident) = field.ident {
             if ident.name == kw::Underscore {
-                self.check_anonymous_field(field);
                 self.visit_vis(&field.vis);
                 self.visit_ident(ident);
                 self.visit_ty_common(&field.ty);
@@ -251,66 +245,6 @@ fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
         err.emit();
     }
 
-    fn check_anonymous_field(&self, field: &FieldDef) {
-        let FieldDef { ty, .. } = field;
-        match &ty.kind {
-            TyKind::AnonymousStruct(..) | TyKind::AnonymousUnion(..) => {
-                // We already checked for `kw::Underscore` before calling this function,
-                // so skip the check
-            }
-            TyKind::Path(..) => {
-                // If the anonymous field contains a Path as type, we can't determine
-                // if the path is a valid struct or union, so skip the check
-            }
-            _ => {
-                let msg = "unnamed fields can only have struct or union types";
-                let label = "not a struct or union";
-                self.err_handler()
-                    .struct_span_err(field.span, msg)
-                    .span_label(ty.span, label)
-                    .emit();
-            }
-        }
-    }
-
-    fn deny_anonymous_struct(&self, ty: &Ty) {
-        match &ty.kind {
-            TyKind::AnonymousStruct(..) => {
-                self.err_handler()
-                    .struct_span_err(
-                        ty.span,
-                        "anonymous structs are not allowed outside of unnamed struct or union fields",
-                    )
-                    .span_label(ty.span, "anonymous struct declared here")
-                    .emit();
-            }
-            TyKind::AnonymousUnion(..) => {
-                self.err_handler()
-                    .struct_span_err(
-                        ty.span,
-                        "anonymous unions are not allowed outside of unnamed struct or union fields",
-                    )
-                    .span_label(ty.span, "anonymous union declared here")
-                    .emit();
-            }
-            _ => {}
-        }
-    }
-
-    fn deny_anonymous_field(&self, field: &FieldDef) {
-        if let Some(ident) = field.ident {
-            if ident.name == kw::Underscore {
-                self.err_handler()
-                    .struct_span_err(
-                        field.span,
-                        "anonymous fields are not allowed outside of structs or unions",
-                    )
-                    .span_label(ident.span, "anonymous field declared here")
-                    .emit()
-            }
-        }
-    }
-
     fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
         for Param { pat, .. } in &decl.inputs {
             match pat.kind {
@@ -1081,7 +1015,6 @@ fn visit_expr(&mut self, expr: &'a Expr) {
 
     fn visit_ty(&mut self, ty: &'a Ty) {
         self.visit_ty_common(ty);
-        self.deny_anonymous_struct(ty);
         self.walk_ty(ty)
     }
 
@@ -1096,7 +1029,6 @@ fn visit_lifetime(&mut self, lifetime: &'a Lifetime) {
     }
 
     fn visit_field_def(&mut self, s: &'a FieldDef) {
-        self.deny_anonymous_field(s);
         visit::walk_field_def(self, s)
     }
 
@@ -1669,7 +1601,9 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
                 walk_list!(self, visit_ty, ty);
             }
             AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body))
-                if self.in_const_trait_impl || ctxt == AssocCtxt::Trait =>
+                if self.in_const_trait_impl
+                    || ctxt == AssocCtxt::Trait
+                    || matches!(sig.header.constness, Const::Yes(_)) =>
             {
                 self.visit_vis(&item.vis);
                 self.visit_ident(item.ident);
index 1defb65ed8793d9ef7142dcacee8935f5a95ec43..06e9d9ed329331e3d18e72d77ba7c45f2baea978 100644 (file)
@@ -668,7 +668,6 @@ macro_rules! gate_all {
         // involved, so we only emit errors where there are no other parsing errors.
         gate_all!(destructuring_assignment, "destructuring assignments are unstable");
     }
-    gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
 
     // All uses of `gate_all!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
@@ -703,10 +702,16 @@ macro_rules! gate_all {
 }
 
 fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
+    // checks if `#![feature]` has been used to enable any lang feature
+    // does not check the same for lib features unless there's at least one
+    // declared lang feature
     use rustc_errors::Applicability;
 
     if !sess.opts.unstable_features.is_nightly_build() {
         let lang_features = &sess.features_untracked().declared_lang_features;
+        if lang_features.len() == 0 {
+            return;
+        }
         for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
             let mut err = struct_span_err!(
                 sess.parse_sess.span_diagnostic,
index 3cf04be160c64a0a8003493187d618cbca4217a2..c24882086e12d16d1b808e6f4270adebd4820658 100644 (file)
@@ -985,14 +985,6 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
                 }
                 self.pclose();
             }
-            ast::TyKind::AnonymousStruct(ref fields, ..) => {
-                self.head("struct");
-                self.print_record_struct_body(&fields, ty.span);
-            }
-            ast::TyKind::AnonymousUnion(ref fields, ..) => {
-                self.head("union");
-                self.print_record_struct_body(&fields, ty.span);
-            }
             ast::TyKind::Paren(ref typ) => {
                 self.popen();
                 self.print_type(typ);
@@ -1413,7 +1405,12 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
         }
     }
 
-    crate fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) {
+    crate fn print_record_struct_body(
+        &mut self,
+        fields: &Vec<ast::FieldDef>,
+        span: rustc_span::Span,
+    ) {
+        self.nbsp();
         self.bopen();
         self.hardbreak_if_not_bol();
 
@@ -1462,7 +1459,6 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
             }
             ast::VariantData::Struct(ref fields, ..) => {
                 self.print_where_clause(&generics.where_clause);
-                self.nbsp();
                 self.print_record_struct_body(fields, span);
             }
         }
index f6e4e3888418fb22d848f7b63f1ebf6a7b13a5ec..4333038a6f936618c6f683dd6b4230fbd104a15a 100644 (file)
@@ -14,7 +14,9 @@
 };
 
 /// This function computes Polonius facts for the given body. It makes a copy of
-/// the body because it needs to regenerate the region identifiers.
+/// the body because it needs to regenerate the region identifiers. This function
+/// should never be invoked during a typical compilation session due to performance
+/// issues with Polonius.
 ///
 /// Note:
 /// *   This function will panic if the required body was already stolen. This
@@ -22,8 +24,6 @@
 ///     because they are evaluated during typechecking. The panic can be avoided
 ///     by overriding the `mir_borrowck` query. You can find a complete example
 ///     that shows how to do this at `src/test/run-make/obtain-borrowck/`.
-/// *   This function will also panic if computation of Polonius facts
-///     (`-Zpolonius` flag) is not enabled.
 ///
 /// *   Polonius is highly unstable, so expect regular changes in its signature or other details.
 pub fn get_body_with_borrowck_facts<'tcx>(
index 3c11408458629dfe84b6bb40ef6e05cfa38f9db7..b23ce281bef24de4ed1b6ef045744f2ff25bcb95 100644 (file)
@@ -336,15 +336,15 @@ fn report_cannot_move_from_borrowed_content(
                 if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
             {
                 let closure_kind_ty = closure_substs.as_closure().kind_ty();
-                let closure_kind = closure_kind_ty.to_opt_closure_kind();
-                let capture_description = match closure_kind {
-                    Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
-                    Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
+                let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
+                    Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
                     Some(ty::ClosureKind::FnOnce) => {
                         bug!("closure kind does not match first argument type")
                     }
                     None => bug!("closure kind not inferred by borrowck"),
                 };
+                let capture_description =
+                    format!("captured variable in an `{}` closure", closure_kind);
 
                 let upvar = &self.upvars[upvar_field.unwrap().index()];
                 let upvar_hir_id = upvar.place.get_root_variable();
@@ -368,6 +368,10 @@ fn report_cannot_move_from_borrowed_content(
                 let mut diag = self.cannot_move_out_of(span, &place_description);
 
                 diag.span_label(upvar_span, "captured outer variable");
+                diag.span_label(
+                    self.body.span,
+                    format!("captured by this `{}` closure", closure_kind),
+                );
 
                 diag
             }
index 4e4b8a953cd1228c177dc07f90b45a2ea6464069..b3b7d7e02ccef068b444607116f3058a20ba0f10 100644 (file)
@@ -154,11 +154,6 @@ fn do_mir_borrowck<'a, 'tcx>(
 
     debug!("do_mir_borrowck(def = {:?})", def);
 
-    assert!(
-        !return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius,
-        "borrowck facts can be requested only when Polonius is enabled"
-    );
-
     let tcx = infcx.tcx;
     let param_env = tcx.param_env(def.did);
     let id = tcx.hir().local_def_id_to_hir_id(def.did);
@@ -235,6 +230,8 @@ fn do_mir_borrowck<'a, 'tcx>(
     let borrow_set =
         Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
 
+    let use_polonius = return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius;
+
     // Compute non-lexical lifetimes.
     let nll::NllOutput {
         regioncx,
@@ -254,6 +251,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         &mdpe.move_data,
         &borrow_set,
         &upvars,
+        use_polonius,
     );
 
     // Dump MIR results into a file, if that is enabled. This let us
index 8b2c0362261ca9ac4e6aacac8c979e221933a203..477b049b07596cda7b1c7eed0399d82fdf7938cb 100644 (file)
@@ -164,8 +164,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     move_data: &MoveData<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
     upvars: &[Upvar<'tcx>],
+    use_polonius: bool,
 ) -> NllOutput<'tcx> {
-    let mut all_facts = AllFacts::enabled(infcx.tcx).then_some(AllFacts::default());
+    let mut all_facts =
+        (use_polonius || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default());
 
     let universal_regions = Rc::new(universal_regions);
 
@@ -281,7 +283,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
             all_facts.write_to_dir(dir_path, location_table).unwrap();
         }
 
-        if infcx.tcx.sess.opts.debugging_opts.polonius {
+        if use_polonius {
             let algorithm =
                 env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid"));
             let algorithm = Algorithm::from_str(&algorithm).unwrap();
index 39b83e5043101bbde09f54f02f7f1862dc3c7b43..d790e31105c8aa2f2ee20c82662dce9c1a473959 100644 (file)
@@ -46,7 +46,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// Calling `universal_upper_bound` for such a region gives `fr_fn_body`,
     /// which has no `external_name` in which case we use `'empty` as the
     /// region to pass to `infer_opaque_definition_from_instantiation`.
-    #[instrument(skip(self, infcx))]
+    #[instrument(level = "debug", skip(self, infcx))]
     pub(crate) fn infer_opaque_types(
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
index 3e757827a5e6cff52c5d922973c634ac4dade462..41c004ea59608e75426422d2000a202e9906ce5e 100644 (file)
@@ -1998,7 +1998,6 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
                                     &obligation,
                                     &traits::SelectionError::Unimplemented,
                                     false,
-                                    false,
                                 );
                             }
                         }
index 14506f296bf95d294964445da692c648ceceacdc..ecf70da6d96c58d6e1b73c5edc2c3167c6655e45 100644 (file)
@@ -65,15 +65,29 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     // We want to make sure we have the ctxt set so that we can use unstable methods
     let span = cx.with_def_site_ctxt(span);
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
+    let fmt = substr.nonself_args[0].clone();
+
+    // Special fast path for unit variants. In the common case of an enum that is entirely unit
+    // variants (i.e. a C-like enum), this fast path allows LLVM to eliminate the entire switch in
+    // favor of a lookup table.
+    if let ast::VariantData::Unit(..) = vdata {
+        let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
+        let expr = cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]);
+        let stmts = vec![cx.stmt_expr(expr)];
+        let block = cx.block(span, stmts);
+        return cx.expr_block(block);
+    }
+
     let builder = Ident::new(sym::debug_trait_builder, span);
     let builder_expr = cx.expr_ident(span, builder);
 
-    let fmt = substr.nonself_args[0].clone();
-
     let mut stmts = Vec::with_capacity(fields.len() + 2);
     let fn_path_finish;
     match vdata {
-        ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
+        ast::VariantData::Unit(..) => {
+            cx.span_bug(span, "unit variants should have been handled above");
+        }
+        ast::VariantData::Tuple(..) => {
             // tuple struct/"normal" variant
             let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]);
             let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]);
index 521ce344180a1063fdbee45863a2c64df17b07d3..3c99febbd57cc952faafcf62a69101e9dbb8d231 100644 (file)
@@ -16,6 +16,7 @@ snap = "1"
 tracing = "0.1"
 rustc_middle = { path = "../rustc_middle" }
 rustc-demangle = "0.1.21"
+rustc_arena = { path = "../rustc_arena" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 rustc_data_structures = { path = "../rustc_data_structures" }
index f913c3e4b703d4bcc00306d595de20c372c1c188..9272435a330a5f00dca8d749988a64faaaf90496 100644 (file)
@@ -34,7 +34,7 @@
 use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{self, DebugInfo};
-use rustc_span::symbol::{Interner, Symbol};
+use rustc_span::symbol::Symbol;
 use rustc_span::FileNameDisplayPreference;
 use rustc_span::{self, SourceFile, SourceFileHash, Span};
 use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, TagEncoding};
@@ -89,8 +89,54 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
 
-#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
-pub struct UniqueTypeId(Symbol);
+mod unique_type_id {
+    use super::*;
+    use rustc_arena::DroplessArena;
+
+    #[derive(Copy, Hash, Eq, PartialEq, Clone)]
+    pub(super) struct UniqueTypeId(u32);
+
+    // The `&'static str`s in this type actually point into the arena.
+    //
+    // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
+    // found that to regress performance up to 2% in some cases. This might be
+    // revisited after further improvements to `indexmap`.
+    #[derive(Default)]
+    pub(super) struct TypeIdInterner {
+        arena: DroplessArena,
+        names: FxHashMap<&'static str, UniqueTypeId>,
+        strings: Vec<&'static str>,
+    }
+
+    impl TypeIdInterner {
+        #[inline]
+        pub(super) fn intern(&mut self, string: &str) -> UniqueTypeId {
+            if let Some(&name) = self.names.get(string) {
+                return name;
+            }
+
+            let name = UniqueTypeId(self.strings.len() as u32);
+
+            // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
+            // UTF-8.
+            let string: &str =
+                unsafe { std::str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
+            // It is safe to extend the arena allocation to `'static` because we only access
+            // these while the arena is still alive.
+            let string: &'static str = unsafe { &*(string as *const str) };
+            self.strings.push(string);
+            self.names.insert(string, name);
+            name
+        }
+
+        // Get the symbol as a string. `Symbol::as_str()` should be used in
+        // preference to this function.
+        pub(super) fn get(&self, symbol: UniqueTypeId) -> &str {
+            self.strings[symbol.0 as usize]
+        }
+    }
+}
+use unique_type_id::*;
 
 /// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
 /// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
@@ -99,7 +145,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 #[derive(Default)]
 pub struct TypeMap<'ll, 'tcx> {
     /// The `UniqueTypeId`s created so far.
-    unique_id_interner: Interner,
+    unique_id_interner: TypeIdInterner,
     /// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping.
     unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
     /// A map from types to debuginfo metadata. This is an N:1 mapping.
@@ -166,8 +212,7 @@ fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'
     /// Gets the string representation of a `UniqueTypeId`. This method will fail if
     /// the ID is unknown.
     fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
-        let UniqueTypeId(interner_key) = unique_type_id;
-        self.unique_id_interner.get(interner_key)
+        self.unique_id_interner.get(unique_type_id)
     }
 
     /// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given
@@ -197,9 +242,9 @@ fn get_unique_type_id_of_type<'a>(
         let unique_type_id = hasher.finish::<Fingerprint>().to_hex();
 
         let key = self.unique_id_interner.intern(&unique_type_id);
-        self.type_to_unique_id.insert(type_, UniqueTypeId(key));
+        self.type_to_unique_id.insert(type_, key);
 
-        UniqueTypeId(key)
+        key
     }
 
     /// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really
@@ -215,7 +260,7 @@ fn get_unique_type_id_of_enum_variant<'a>(
         let enum_variant_type_id =
             format!("{}::{}", self.get_unique_type_id_as_string(enum_type_id), variant_name);
         let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
-        UniqueTypeId(interner_key)
+        interner_key
     }
 
     /// Gets the unique type ID string for an enum variant part.
index 4fb51ecc1d347db0789d6e6de2fd03f73f6b6e8e..826c09cd948f649e0edf10d9cf26b6e835b06ae9 100644 (file)
@@ -637,7 +637,7 @@ fn link_dwarf_object<'a>(sess: &'a Session, executable_out_filename: &Path) {
     cmd.arg("-o");
     cmd.arg(&dwp_out_filename);
 
-    let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+    let mut new_path = sess.get_tools_search_paths(false);
     if let Some(path) = env::var_os("PATH") {
         new_path.extend(env::split_paths(&path));
     }
@@ -2555,8 +2555,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
             match ld_impl {
                 LdImpl::Lld => {
                     if sess.target.lld_flavor == LldFlavor::Ld64 {
-                        let tools_path =
-                            sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+                        let tools_path = sess.get_tools_search_paths(false);
                         let ld64_exe = tools_path
                             .into_iter()
                             .map(|p| p.join("gcc-ld"))
@@ -2571,8 +2570,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
                             arg
                         });
                     } else {
-                        let tools_path =
-                            sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+                        let tools_path = sess.get_tools_search_paths(false);
                         let lld_path = tools_path
                             .into_iter()
                             .map(|p| p.join("gcc-ld"))
index 9e1c6a169f1525235ac04d526f6a54dd944cd6b4..e3b0eea0d89c70ac0dd0988731bc6352852efa72 100644 (file)
@@ -15,7 +15,6 @@
 use rustc_middle::ty::TyCtxt;
 use rustc_serialize::{json, Encoder};
 use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
-use rustc_session::search_paths::PathKind;
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor};
@@ -101,7 +100,7 @@ pub fn get_linker<'a>(
 
     // The compiler's sysroot often has some bundled tools, so add it to the
     // PATH for the child.
-    let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained);
+    let mut new_path = sess.get_tools_search_paths(self_contained);
     let mut msvc_changed_path = false;
     if sess.target.is_like_msvc {
         if let Some(ref tool) = msvc_tool {
index 171fc45ea4696c4ed5b414ff68b3ba15fba522e9..57af0ff07143373cacfd7f11d2423e7e0bc8cd7c 100644 (file)
@@ -51,10 +51,11 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     assert!(!layout.is_unsized());
     let ret = ecx.allocate(layout, MemoryKind::Stack)?;
 
-    let name =
-        with_no_trimmed_paths(|| ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id())));
-    let prom = cid.promoted.map_or_else(String::new, |p| format!("::promoted[{:?}]", p));
-    trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
+    trace!(
+        "eval_body_using_ecx: pushing stack frame for global: {}{}",
+        with_no_trimmed_paths(|| ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()))),
+        cid.promoted.map_or_else(String::new, |p| format!("::promoted[{:?}]", p))
+    );
 
     ecx.push_stack_frame(
         cid.instance,
index 40419a4d201ac0b198ab799ebf509a020ea23b7e..10afd9560fa956da688e68238a35b12d5c9a435e 100644 (file)
@@ -1,5 +1,5 @@
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::DefId;
 use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
@@ -34,8 +34,14 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
 }
 
 pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
-    let parent_id = tcx.hir().get_parent_did(hir_id);
-    if !parent_id.is_top_level_module() { is_const_impl_raw(tcx, parent_id) } else { false }
+    let parent_id = tcx.hir().get_parent_node(hir_id);
+    matches!(
+        tcx.hir().get(parent_id),
+        hir::Node::Item(hir::Item {
+            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
+            ..
+        })
+    )
 }
 
 /// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
@@ -70,19 +76,6 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     }
 }
 
-/// Checks whether the given item is an `impl` that has a `const` modifier.
-fn is_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let node = tcx.hir().get(hir_id);
-    matches!(
-        node,
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
-            ..
-        })
-    )
-}
-
 fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     is_const_fn(tcx, def_id)
         && match tcx.lookup_const_stability(def_id) {
@@ -103,10 +96,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 }
 
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        is_const_fn_raw,
-        is_const_impl_raw: |tcx, def_id| is_const_impl_raw(tcx, def_id.expect_local()),
-        is_promotable_const_fn,
-        ..*providers
-    };
+    *providers = Providers { is_const_fn_raw, is_promotable_const_fn, ..*providers };
 }
index 8a90686b9003f5c391cd1e7a077969ab1a12a42c..ae20f6f97b2124ad6099d4c5a1b2a114ab3e26fc 100644 (file)
@@ -36,12 +36,17 @@ fn hook_panic_fn(
         let def_id = instance.def_id();
         if Some(def_id) == self.tcx.lang_items().panic_fn()
             || Some(def_id) == self.tcx.lang_items().panic_str()
+            || Some(def_id) == self.tcx.lang_items().panic_display()
             || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
         {
-            // &str
+            // &str or &&str
             assert!(args.len() == 1);
 
-            let msg_place = self.deref_operand(&args[0])?;
+            let mut msg_place = self.deref_operand(&args[0])?;
+            while msg_place.layout.ty.is_ref() {
+                msg_place = self.deref_operand(&msg_place.into())?;
+            }
+
             let msg = Symbol::intern(self.read_str(&msg_place)?);
             let span = self.find_closest_untracked_caller_location();
             let (file, line, col) = self.location_triple_for_span(span);
index b032ee96ce7b033a46f4db32cad8fc86e095ab5d..698742fe98ceb0e5868c2510b9cb9f4c6a955630 100644 (file)
@@ -62,15 +62,10 @@ fn numeric_intrinsic<Tag>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<T
             ensure_monomorphic_enough(tcx, tp_ty)?;
             ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
         }
-        sym::min_align_of | sym::pref_align_of => {
+        sym::pref_align_of => {
             // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
             let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
-            let n = match name {
-                sym::pref_align_of => layout.align.pref.bytes(),
-                sym::min_align_of => layout.align.abi.bytes(),
-                _ => bug!(),
-            };
-            ConstValue::from_machine_usize(n, &tcx)
+            ConstValue::from_machine_usize(layout.align.pref.bytes(), &tcx)
         }
         sym::type_id => {
             ensure_monomorphic_enough(tcx, tp_ty)?;
index 02b317b89810620357e2d88e0ef298b198845063..0e5a896a8f18ba332cdc4490e8a380c7ed65a5c2 100644 (file)
@@ -22,7 +22,7 @@
 use std::ops::Deref;
 
 use super::ops::{self, NonConstOp, Status};
-use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
+use super::qualifs::{self, CustomEq, HasMutInterior, NeedsNonConstDrop};
 use super::resolver::FlowSensitiveAnalysis;
 use super::{is_lang_panic_fn, ConstCx, Qualif};
 use crate::const_eval::is_unstable_const_fn;
@@ -39,7 +39,7 @@
 #[derive(Default)]
 pub struct Qualifs<'mir, 'tcx> {
     has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
-    needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
+    needs_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
     indirectly_mutable: Option<IndirectlyMutableResults<'mir, 'tcx>>,
 }
 
@@ -80,14 +80,14 @@ pub fn needs_drop(
         location: Location,
     ) -> bool {
         let ty = ccx.body.local_decls[local].ty;
-        if !NeedsDrop::in_any_value_of_ty(ccx, ty) {
+        if !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
             return false;
         }
 
         let needs_drop = self.needs_drop.get_or_insert_with(|| {
             let ConstCx { tcx, body, .. } = *ccx;
 
-            FlowSensitiveAnalysis::new(NeedsDrop, ccx)
+            FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
                 .into_engine(tcx, &body)
                 .iterate_to_fixpoint()
                 .into_results_cursor(&body)
@@ -888,6 +888,10 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                 if is_lang_panic_fn(tcx, callee) {
                     self.check_op(ops::Panic);
 
+                    // `begin_panic` and `panic_display` are generic functions that accept
+                    // types other than str. Check to enforce that only str can be used in
+                    // const-eval.
+
                     // const-eval of the `begin_panic` fn assumes the argument is `&str`
                     if Some(callee) == tcx.lang_items().begin_panic_fn() {
                         match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
@@ -896,6 +900,15 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                         }
                     }
 
+                    // const-eval of the `panic_display` fn assumes the argument is `&&str`
+                    if Some(callee) == tcx.lang_items().panic_display() {
+                        match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
+                            ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
+                                {}
+                            _ => self.check_op(ops::PanicNonStr),
+                        }
+                    }
+
                     return;
                 }
 
@@ -988,12 +1001,12 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
 
                 let mut err_span = self.span;
 
-                // Check to see if the type of this place can ever have a drop impl. If not, this
-                // `Drop` terminator is frivolous.
-                let ty_needs_drop =
-                    dropped_place.ty(self.body, self.tcx).ty.needs_drop(self.tcx, self.param_env);
+                let ty_needs_non_const_drop = qualifs::NeedsNonConstDrop::in_any_value_of_ty(
+                    self.ccx,
+                    dropped_place.ty(self.body, self.tcx).ty,
+                );
 
-                if !ty_needs_drop {
+                if !ty_needs_non_const_drop {
                     return;
                 }
 
index a5cb0f4e14b178547dc1c1f6ae305f748b3d8183..d1fd3ceaa589a4e112d672cfbe3dea0ec4042ceb 100644 (file)
@@ -79,6 +79,7 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
     // Keep in sync with what that function handles!
     Some(def_id) == tcx.lang_items().panic_fn()
         || Some(def_id) == tcx.lang_items().panic_str()
+        || Some(def_id) == tcx.lang_items().panic_display()
         || Some(def_id) == tcx.lang_items().begin_panic_fn()
         || Some(def_id) == tcx.lang_items().panic_fmt()
         || Some(def_id) == tcx.lang_items().begin_panic_fmt()
index 8923d989b2944a63796842d5e1f6cbddf2e60e26..2a29675083888e9a8021e9e7082c89200027f91d 100644 (file)
@@ -599,12 +599,21 @@ fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
         }
 
         fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-            feature_err(
+            let mut builder = feature_err(
                 &ccx.tcx.sess.parse_sess,
                 sym::const_fn_trait_bound,
                 span,
                 "trait bounds other than `Sized` on const fn parameters are unstable",
-            )
+            );
+
+            match ccx.fn_sig() {
+                Some(fn_sig) if !fn_sig.span.contains(span) => {
+                    builder.span_label(fn_sig.span, "function declared as const here");
+                }
+                _ => {}
+            }
+
+            builder
         }
     }
 
index b08ce219034ce09eb5b38d2b4dd7fcea7b7b5959..f2ba5a1ebb19be757884b27d555268116199e560 100644 (file)
@@ -5,7 +5,7 @@
 
 use super::check::Qualifs;
 use super::ops::{self, NonConstOp};
-use super::qualifs::{NeedsDrop, Qualif};
+use super::qualifs::{NeedsNonConstDrop, Qualif};
 use super::ConstCx;
 
 /// Returns `true` if we should use the more precise live drop checker that runs after drop
@@ -78,10 +78,10 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc
         match &terminator.kind {
             mir::TerminatorKind::Drop { place: dropped_place, .. } => {
                 let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
-                if !NeedsDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
-                    bug!(
-                        "Drop elaboration left behind a Drop for a type that does not need dropping"
-                    );
+                if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
+                    // Instead of throwing a bug, we just return here. This is because we have to
+                    // run custom `const Drop` impls.
+                    return;
                 }
 
                 if dropped_place.is_indirect() {
index 413a9638eb37b172717d4473f48079215170cf72..cb9b4bcb77a8574ea8baa50bd54b1c3e95587de1 100644 (file)
@@ -3,10 +3,14 @@
 //! See the `Qualif` trait for more info.
 
 use rustc_errors::ErrorReported;
+use rustc_hir as hir;
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
 use rustc_span::DUMMY_SP;
-use rustc_trait_selection::traits;
+use rustc_trait_selection::traits::{
+    self, ImplSource, Obligation, ObligationCause, SelectionContext,
+};
 
 use super::ConstCx;
 
@@ -17,7 +21,7 @@ pub fn in_any_value_of_ty(
 ) -> ConstQualifs {
     ConstQualifs {
         has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
-        needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
+        needs_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
         custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
         error_occured,
     }
@@ -97,22 +101,58 @@ fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tc
 /// This must be ruled out (a) because we cannot run `Drop` during compile-time
 /// as that might not be a `const fn`, and (b) because implicit promotion would
 /// remove side-effects that occur as part of dropping that value.
-pub struct NeedsDrop;
+pub struct NeedsNonConstDrop;
 
-impl Qualif for NeedsDrop {
-    const ANALYSIS_NAME: &'static str = "flow_needs_drop";
+impl Qualif for NeedsNonConstDrop {
+    const ANALYSIS_NAME: &'static str = "flow_needs_nonconst_drop";
     const IS_CLEARED_ON_MOVE: bool = true;
 
     fn in_qualifs(qualifs: &ConstQualifs) -> bool {
         qualifs.needs_drop
     }
 
-    fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        ty.needs_drop(cx.tcx, cx.param_env)
+    fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
+        // Avoid selecting for simple cases.
+        match ty::util::needs_drop_components(ty, &cx.tcx.data_layout).as_deref() {
+            Ok([]) => return false,
+            Err(ty::util::AlwaysRequiresDrop) => return true,
+            // If we've got a single component, select with that
+            // to increase the chance that we hit the selection cache.
+            Ok([t]) => ty = t,
+            Ok([..]) => {}
+        }
+
+        let drop_trait = if let Some(did) = cx.tcx.lang_items().drop_trait() {
+            did
+        } else {
+            // there is no way to define a type that needs non-const drop
+            // without having the lang item present.
+            return false;
+        };
+        let trait_ref =
+            ty::TraitRef { def_id: drop_trait, substs: cx.tcx.mk_substs_trait(ty, &[]) };
+        let obligation = Obligation::new(
+            ObligationCause::dummy(),
+            cx.param_env,
+            ty::Binder::dummy(ty::TraitPredicate {
+                trait_ref,
+                constness: ty::BoundConstness::ConstIfConst,
+            }),
+        );
+
+        let implsrc = cx.tcx.infer_ctxt().enter(|infcx| {
+            let mut selcx = SelectionContext::with_constness(&infcx, hir::Constness::Const);
+            selcx.select(&obligation)
+        });
+        match implsrc {
+            Ok(Some(ImplSource::ConstDrop(_)))
+            | Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => false,
+            _ => true,
+        }
     }
 
     fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
-        adt.has_dtor(cx.tcx)
+        adt.has_non_const_dtor(cx.tcx)
     }
 }
 
index 8c24c9fa9769cff229679c50544c1f126988a1e2..52d04cb4ff1e0f689a6794e6d5d7631b4ece72fd 100644 (file)
@@ -231,7 +231,7 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> {
 
                         // We cannot promote things that need dropping, since the promoted value
                         // would not get dropped.
-                        if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
+                        if self.qualif_local::<qualifs::NeedsNonConstDrop>(place.local) {
                             return Err(Unpromotable);
                         }
 
index 53053327d0dab276b0c90134b18854a84d0fe483..4c6a2baaef1e512972460433edf13ae172d8b5fd 100644 (file)
@@ -677,10 +677,7 @@ fn print_crate_info(
                     println!("{}", targets.join("\n"));
                 }
                 Sysroot => println!("{}", sess.sysroot.display()),
-                TargetLibdir => println!(
-                    "{}",
-                    sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display()
-                ),
+                TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()),
                 TargetSpec => println!("{}", sess.target.to_json().pretty()),
                 FileNames | CrateName => {
                     let input = input.unwrap_or_else(|| {
index bc2c03a0220826f81558b003a18cbd71a891f04e..a6d6d19762b58dde38260fbbfd5842a6a95d012c 100644 (file)
@@ -15,13 +15,13 @@ form of initializer was used.
 For example, the code above can be fixed to:
 
 ```
-enum Foo {
-    FirstValue(i32)
-}
+type U32 = u32;
+let t: U32 = 4;
+```
 
-fn main() {
-    let u = Foo::FirstValue(0i32);
+or:
 
-    let t = 4;
-}
+```
+struct U32 { value: u32 }
+let t = U32 { value: 4 };
 ```
index 232cf4bdb7f614ddf5b07d1a3afc5c8dde57c768..41a73268f467345df99ff6b6e57fb967fd2aada6 100644 (file)
@@ -74,6 +74,10 @@ pub fn normal<S: Into<String>>(t: S) -> DiagnosticStyledString {
     pub fn highlighted<S: Into<String>>(t: S) -> DiagnosticStyledString {
         DiagnosticStyledString(vec![StringPart::Highlighted(t.into())])
     }
+
+    pub fn content(&self) -> String {
+        self.0.iter().map(|x| x.content()).collect::<String>()
+    }
 }
 
 #[derive(Debug, PartialEq, Eq)]
@@ -82,6 +86,14 @@ pub enum StringPart {
     Highlighted(String),
 }
 
+impl StringPart {
+    pub fn content(&self) -> &str {
+        match self {
+            &StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s,
+        }
+    }
+}
+
 impl Diagnostic {
     pub fn new(level: Level, message: &str) -> Self {
         Diagnostic::new_with_code(level, None, message)
index fb7479eafc86f5e155640393e1efd8891f4c5873..363cc72b52c3e5bc46483c5b94f796bde701144f 100644 (file)
@@ -72,7 +72,7 @@ pub(super) fn parse(
                                             // this with just `span.edition()`. A
                                             // `SyntaxContext::root()` from the current crate will
                                             // have the edition of the current crate, and a
-                                            // `SyntaxxContext::root()` from a foreign crate will
+                                            // `SyntaxContext::root()` from a foreign crate will
                                             // have the edition of that crate (which we manually
                                             // retrieve via the `edition` parameter).
                                             if span.ctxt() == SyntaxContext::root() {
index 366ed715434eda4e2598b6ea7558588881b43e72..efa93c186363a1570e100b657ecf8a8afbe3490e 100644 (file)
@@ -638,9 +638,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows specifying the as-needed link modifier
     (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
 
-    /// Allows unnamed fields of struct and union type
-    (incomplete, unnamed_fields, "1.53.0", Some(49804), None),
-
     /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
     (active, more_qualified_paths, "1.54.0", Some(86935), None),
 
index 84bc37170c6346d1bd819d54bacb17972cd0c900..5655c4c0e973ef3cd70c165617a394aa52c39b57 100644 (file)
@@ -3234,12 +3234,7 @@ pub fn hir_id(&self) -> Option<HirId> {
         }
     }
 
-    /// Returns `Constness::Const` when this node is a const fn/impl/item,
-    ///
-    /// HACK(fee1-dead): or an associated type in a trait. This works because
-    /// only typeck cares about const trait predicates, so although the predicates
-    /// query would return const predicates when it does not need to be const,
-    /// it wouldn't have any effect.
+    /// Returns `Constness::Const` when this node is a const fn/impl/item.
     pub fn constness_for_typeck(&self) -> Constness {
         match self {
             Node::Item(Item {
@@ -3258,7 +3253,6 @@ pub fn constness_for_typeck(&self) -> Constness {
 
             Node::Item(Item { kind: ItemKind::Const(..), .. })
             | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
-            | Node::TraitItem(TraitItem { kind: TraitItemKind::Type(..), .. })
             | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
 
             _ => Constness::NotConst,
index b85ed0cb4bbe59ecc1b2e707342cea7aefbc4eb2..d69a247054026f9a403ecbd9851d8f0416e15fff 100644 (file)
@@ -283,6 +283,7 @@ pub fn extract<'a, F>(check_name: F, attrs: &'a [ast::Attribute]) -> Option<(Sym
     // a weak lang item, but do not have it defined.
     Panic,                   sym::panic,               panic_fn,                   Target::Fn,             GenericRequirement::None;
     PanicFmt,                sym::panic_fmt,           panic_fmt,                  Target::Fn,             GenericRequirement::None;
+    PanicDisplay,            sym::panic_display,       panic_display,              Target::Fn,             GenericRequirement::None;
     PanicStr,                sym::panic_str,           panic_str,                  Target::Fn,             GenericRequirement::None;
     ConstPanicFmt,           sym::const_panic_fmt,     const_panic_fmt,            Target::Fn,             GenericRequirement::None;
     PanicBoundsCheck,        sym::panic_bounds_check,  panic_bounds_check_fn,      Target::Fn,             GenericRequirement::None;
index 1139b714d0a1ff155b8055258a14dae507ad88d3..b8089b2499b66524bef2f6ef2da45291c4e6af9c 100644 (file)
@@ -1971,6 +1971,8 @@ pub fn report_and_explain_type_error(
         trace: TypeTrace<'tcx>,
         terr: &TypeError<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
+        use crate::traits::ObligationCauseCode::MatchExpressionArm;
+
         debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
 
         let span = trace.cause.span(self.tcx);
@@ -2013,6 +2015,19 @@ pub fn report_and_explain_type_error(
                         _ => {}
                     }
                 }
+                if let MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =
+                    trace.cause.code
+                {
+                    if let hir::MatchSource::TryDesugar = source {
+                        if let Some((expected_ty, found_ty)) = self.values_str(trace.values) {
+                            err.note(&format!(
+                                "`?` operator cannot convert from `{}` to `{}`",
+                                found_ty.content(),
+                                expected_ty.content(),
+                            ));
+                        }
+                    }
+                }
                 err
             }
             FailureCode::Error0644(failure_str) => {
@@ -2585,9 +2600,7 @@ fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
             CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
             MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
                 Error0308(match source {
-                    hir::MatchSource::TryDesugar => {
-                        "try expression alternatives have incompatible types"
-                    }
+                    hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
                     _ => "`match` arms have incompatible types",
                 })
             }
index c60a7149e40eb30bb85f019df45857eff2b0f3ca..593d06bad7b02bf14adcde627327710befd841b6 100644 (file)
@@ -29,7 +29,13 @@ pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorReport
             SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
             _ => return None,
         };
-        let (parent, impl_def_id) = match &cause.code {
+        // If we added a "points at argument expression" obligation, we remove it here, we care
+        // about the original obligation only.
+        let code = match &cause.code {
+            ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => &*parent_code,
+            _ => &cause.code,
+        };
+        let (parent, impl_def_id) = match code {
             ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
             _ => return None,
         };
index d0bd508bc257f2dfd4fd63b71bdd0e65c669a7f2..9dbfa3a850ba848d505e469ac4edf8ee44f33f3b 100644 (file)
@@ -83,10 +83,6 @@ pub fn report_object_safety_error(
                     messages.push(msg.clone());
                 }
             }
-            if trait_span.is_some() {
-                // Only provide the help if its a local trait, otherwise it's not actionable.
-                violation.solution(&mut err);
-            }
         }
     }
     let has_multi_span = !multi_span.is_empty();
@@ -104,5 +100,13 @@ pub fn report_object_safety_error(
          to be resolvable dynamically; for more information visit \
          <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
     );
+    if trait_span.is_some() {
+        let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
+        reported_violations.sort();
+        for violation in reported_violations {
+            // Only provide the help if its a local trait, otherwise it's not actionable.
+            violation.solution(&mut err);
+        }
+    }
     err
 }
index b450c398946e5c66e5c2d4286c0e3121a4190d10..e1d6982f164448c1f279779e78a2dc55960917ce 100644 (file)
@@ -66,10 +66,6 @@ pub struct Obligation<'tcx, T> {
 pub struct FulfillmentError<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
     pub code: FulfillmentErrorCode<'tcx>,
-    /// Diagnostics only: we opportunistically change the `code.span` when we encounter an
-    /// obligation error caused by a call argument. When this is the case, we also signal that in
-    /// this field to ensure accuracy of suggestions.
-    pub points_at_arg_span: bool,
     /// Diagnostics only: the 'root' obligation which resulted in
     /// the failure to process `obligation`. This is the obligation
     /// that was initially passed to `register_predicate_obligation`
@@ -128,7 +124,7 @@ pub fn new(
         code: FulfillmentErrorCode<'tcx>,
         root_obligation: PredicateObligation<'tcx>,
     ) -> FulfillmentError<'tcx> {
-        FulfillmentError { obligation, code, points_at_arg_span: false, root_obligation }
+        FulfillmentError { obligation, code, root_obligation }
     }
 }
 
index 33bddf1dedc1b2a6fa055207cbc5892b66e1357e..e2c13d20a9a5b5a7c11d7a0ec4b22c5e1cef1c93 100644 (file)
@@ -153,47 +153,6 @@ pub fn insert_ty(&mut self, key: ProjectionCacheKey<'tcx>, value: NormalizedTy<'
         assert!(!fresh_key, "never started projecting `{:?}`", key);
     }
 
-    /// Mark the relevant projection cache key as having its derived obligations
-    /// complete, so they won't have to be re-computed (this is OK to do in a
-    /// snapshot - if the snapshot is rolled back, the obligations will be
-    /// marked as incomplete again).
-    pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>) {
-        let mut map = self.map();
-        let ty = match map.get(&key) {
-            Some(&ProjectionCacheEntry::NormalizedTy(ref ty)) => {
-                debug!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty);
-                ty.value
-            }
-            ref value => {
-                // Type inference could "strand behind" old cache entries. Leave
-                // them alone for now.
-                debug!("ProjectionCacheEntry::complete({:?}) - ignoring {:?}", key, value);
-                return;
-            }
-        };
-
-        map.insert(
-            key,
-            ProjectionCacheEntry::NormalizedTy(Normalized { value: ty, obligations: vec![] }),
-        );
-    }
-
-    /// A specialized version of `complete` for when the key's value is known
-    /// to be a NormalizedTy.
-    pub fn complete_normalized(&mut self, key: ProjectionCacheKey<'tcx>, ty: &NormalizedTy<'tcx>) {
-        // We want to insert `ty` with no obligations. If the existing value
-        // already has no obligations (as is common) we don't insert anything.
-        if !ty.obligations.is_empty() {
-            self.map().insert(
-                key,
-                ProjectionCacheEntry::NormalizedTy(Normalized {
-                    value: ty.value,
-                    obligations: vec![],
-                }),
-            );
-        }
-    }
-
     /// Indicates that trying to normalize `key` resulted in
     /// ambiguity. No point in trying it again then until we gain more
     /// type information (in which case, the "fully resolved" key will
index 81433e571021ea94aaceaed02a1bc0680a7c2598..cfe13b1fd4e1fbd060e37dbefb7229f00098435d 100644 (file)
@@ -754,6 +754,7 @@ macro_rules! tracked {
     tracked!(profiler_runtime, "abc".to_string());
     tracked!(relax_elf_relocations, Some(true));
     tracked!(relro_level, Some(RelroLevel::Full));
+    tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
     tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
     tracked!(report_delayed_bugs, true);
     tracked!(sanitizer, SanitizerSet::ADDRESS);
index edb158dd378063228b0376003854828459ac59f2..5435ff1396de800c0841de33c4c74ae4dbfb9df0 100644 (file)
@@ -86,6 +86,7 @@
 
 impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
+        use rustc_middle::ty;
         use rustc_middle::ty::PredicateKind::*;
 
         let predicates = cx.tcx.explicit_predicates_of(item.def_id);
@@ -94,6 +95,10 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
                 Trait(trait_predicate) => trait_predicate,
                 _ => continue,
             };
+            if trait_predicate.constness == ty::BoundConstness::ConstIfConst {
+                // `~const Drop` definitely have meanings so avoid linting here.
+                continue;
+            }
             let def_id = trait_predicate.trait_ref.def_id;
             if cx.tcx.lang_items().drop_trait() == Some(def_id) {
                 // Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
index 0143978cfba5f0eaa629bbe0f29b92cfbec4fa80..d35497c1b381a5460b359e76eb1e43e01eaffd2d 100644 (file)
@@ -851,12 +851,18 @@ fn check_variant_for_ffi(
         use FfiResult::*;
 
         if def.repr.transparent() {
-            // Can assume that only one field is not a ZST, so only check
+            // Can assume that at most one field is not a ZST, so only check
             // that field's type for FFI-safety.
             if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
                 self.check_field_type_for_ffi(cache, field, substs)
             } else {
-                bug!("malformed transparent type");
+                // All fields are ZSTs; this means that the type should behave
+                // like (), which is FFI-unsafe
+                FfiUnsafe {
+                    ty,
+                    reason: "this struct contains only zero-sized fields".into(),
+                    help: None,
+                }
             }
         } else {
             // We can't completely trust repr(C) markings; make sure the fields are
index 8fb678e2d20fb0313633d4b9adccfdf41ab8e4f3..a00561e5213570ab7fa39eb60290a04c1b92b0a8 100644 (file)
         UNSUPPORTED_CALLING_CONVENTIONS,
         BREAK_WITH_LABEL_AND_LOOP,
         UNUSED_ATTRIBUTES,
+        NON_EXHAUSTIVE_OMITTED_PATTERNS,
     ]
 }
 
     Warn,
     "`break` expression with label and unlabeled loop as value expression"
 }
+
+declare_lint! {
+    /// The `non_exhaustive_omitted_patterns` lint detects when a wildcard (`_` or `..`) in a
+    /// pattern for a `#[non_exhaustive]` struct or enum is reachable.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (needs separate crate)
+    /// // crate A
+    /// #[non_exhaustive]
+    /// pub enum Bar {
+    ///     A,
+    ///     B, // added variant in non breaking change
+    /// }
+    ///
+    /// // in crate B
+    /// match Bar::A {
+    ///     Bar::A => {},
+    ///     #[warn(non_exhaustive_omitted_patterns)]
+    ///     _ => {},
+    /// }
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: reachable patterns not covered of non exhaustive enum
+    ///    --> $DIR/reachable-patterns.rs:70:9
+    ///    |
+    /// LL |         _ => {}
+    ///    |         ^ pattern `B` not covered
+    ///    |
+    ///  note: the lint level is defined here
+    ///   --> $DIR/reachable-patterns.rs:69:16
+    ///    |
+    /// LL |         #[warn(non_exhaustive_omitted_patterns)]
+    ///    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    ///    = help: ensure that all possible cases are being handled by adding the suggested match arms
+    ///    = note: the matched value is of type `Bar` and the `non_exhaustive_omitted_patterns` attribute was found
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// Structs and enums tagged with `#[non_exhaustive]` force the user to add a
+    /// (potentially redundant) wildcard when pattern-matching, to allow for future
+    /// addition of fields or variants. The `non_exhaustive_omitted_patterns` lint
+    /// detects when such a wildcard happens to actually catch some fields/variants.
+    /// In other words, when the match without the wildcard would not be exhaustive.
+    /// This lets the user be informed if new fields/variants were added.
+    pub NON_EXHAUSTIVE_OMITTED_PATTERNS,
+    Allow,
+    "detect when patterns of types marked `non_exhaustive` are missed",
+}
index b3f86f3295ae90f602a1f5272f7221956815d56d..b7cad1c3ba6d9367cd57bc247dcdc444a8553193 100644 (file)
@@ -875,7 +875,11 @@ LLVMRustOptimizeWithNewPassManager(
 #if LLVM_VERSION_GE(11, 0)
       OptimizerLastEPCallbacks.push_back(
         [Options](ModulePassManager &MPM, OptimizationLevel Level) {
+#if LLVM_VERSION_GE(14, 0)
+          MPM.addPass(ModuleMemorySanitizerPass(Options));
+#else
           MPM.addPass(MemorySanitizerPass(Options));
+#endif
           MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
         }
       );
@@ -897,7 +901,11 @@ LLVMRustOptimizeWithNewPassManager(
 #if LLVM_VERSION_GE(11, 0)
       OptimizerLastEPCallbacks.push_back(
         [](ModulePassManager &MPM, OptimizationLevel Level) {
+#if LLVM_VERSION_GE(14, 0)
+          MPM.addPass(ModuleThreadSanitizerPass());
+#else
           MPM.addPass(ThreadSanitizerPass());
+#endif
           MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
         }
       );
index 85e990bde86dc0d2f842e8d86516587766a9f1ba..1b245f2a7506080f1d5de9aa83cde69cd67ddb33 100644 (file)
@@ -215,7 +215,7 @@ pub mod sym_generated {
         }
 
         impl Interner {
-            pub fn fresh() -> Self {
+            pub(crate) fn fresh() -> Self {
                 Interner::prefill(&[
                     #prefill_stream
                 ])
index 3eee45a9230d1ffbd68e3d17e55f7e136dc97fbc..c9dc5a0f3b5ec22c3111cbc5198f4f67f85ad823 100644 (file)
@@ -3,7 +3,7 @@
 use rustc_macros::HashStable;
 use rustc_target::abi::{HasDataLayout, Size};
 
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
 use std::fmt;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -20,29 +20,27 @@ fn pointer_size(&self) -> Size {
 
     #[inline]
     fn machine_usize_max(&self) -> u64 {
-        let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
-        u64::try_from(max_usize_plus_1 - 1).unwrap()
+        self.pointer_size().unsigned_int_max().try_into().unwrap()
     }
 
     #[inline]
     fn machine_isize_min(&self) -> i64 {
-        let max_isize_plus_1 = 1i128 << (self.pointer_size().bits() - 1);
-        i64::try_from(-max_isize_plus_1).unwrap()
+        self.pointer_size().signed_int_min().try_into().unwrap()
     }
 
     #[inline]
     fn machine_isize_max(&self) -> i64 {
-        let max_isize_plus_1 = 1u128 << (self.pointer_size().bits() - 1);
-        i64::try_from(max_isize_plus_1 - 1).unwrap()
+        self.pointer_size().signed_int_max().try_into().unwrap()
     }
 
     #[inline]
     fn machine_usize_to_isize(&self, val: u64) -> i64 {
         let val = val as i64;
-        // Now clamp into the machine_isize range.
+        // Now wrap-around into the machine_isize range.
         if val > self.machine_isize_max() {
             // This can only happen the the ptr size is < 64, so we know max_usize_plus_1 fits into
             // i64.
+            debug_assert!(self.pointer_size().bits() < 64);
             let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
             val - i64::try_from(max_usize_plus_1).unwrap()
         } else {
index 985d35ff9a9b18e9d9ddb4e05164f206e5ae25ed..4296acce1ffbe294862ea6bec9ab15f933eafa7c 100644 (file)
         desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
     }
 
-    /// Returns `true` if this is a const `impl`. **Do not call this function manually.**
-    ///
-    /// This query caches the base data for the `is_const_impl` helper function, which also
-    /// takes into account stability attributes (e.g., `#[rustc_const_unstable]`).
-    query is_const_impl_raw(key: DefId) -> bool {
-        desc { |tcx| "checking if item is const impl: `{}`", tcx.def_path_str(key) }
-    }
-
     query asyncness(key: DefId) -> hir::IsAsync {
         desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
     }
index e21a2d1034cdd3e923e8bba1838fc515dca6832a..b4ae56adf328980d4068ccebdc0b8d9348657d08 100644 (file)
@@ -253,6 +253,15 @@ pub enum ObligationCauseCode<'tcx> {
 
     DerivedObligation(DerivedObligationCause<'tcx>),
 
+    FunctionArgumentObligation {
+        /// The node of the relevant argument in the function call.
+        arg_hir_id: hir::HirId,
+        /// The node of the function call.
+        call_hir_id: hir::HirId,
+        /// The obligation introduced by this argument.
+        parent_code: Lrc<ObligationCauseCode<'tcx>>,
+    },
+
     /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplConstObligation,
 
@@ -368,11 +377,12 @@ impl ObligationCauseCode<'_> {
     // Return the base obligation, ignoring derived obligations.
     pub fn peel_derives(&self) -> &Self {
         let mut base_cause = self;
-        while let BuiltinDerivedObligation(cause)
-        | ImplDerivedObligation(cause)
-        | DerivedObligation(cause) = base_cause
+        while let BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
+        | ImplDerivedObligation(DerivedObligationCause { parent_code, .. })
+        | DerivedObligation(DerivedObligationCause { parent_code, .. })
+        | FunctionArgumentObligation { parent_code, .. } = base_cause
         {
-            base_cause = &cause.parent_code;
+            base_cause = &parent_code;
         }
         base_cause
     }
@@ -529,6 +539,9 @@ pub enum ImplSource<'tcx, N> {
 
     /// ImplSource for a trait alias.
     TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
+
+    /// ImplSource for a `const Drop` implementation.
+    ConstDrop(ImplSourceConstDropData),
 }
 
 impl<'tcx, N> ImplSource<'tcx, N> {
@@ -543,7 +556,8 @@ pub fn nested_obligations(self) -> Vec<N> {
             ImplSource::Object(d) => d.nested,
             ImplSource::FnPointer(d) => d.nested,
             ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            | ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
+            | ImplSource::Pointee(ImplSourcePointeeData)
+            | ImplSource::ConstDrop(ImplSourceConstDropData) => Vec::new(),
             ImplSource::TraitAlias(d) => d.nested,
             ImplSource::TraitUpcasting(d) => d.nested,
         }
@@ -560,7 +574,8 @@ pub fn borrow_nested_obligations(&self) -> &[N] {
             ImplSource::Object(d) => &d.nested[..],
             ImplSource::FnPointer(d) => &d.nested[..],
             ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            | ImplSource::Pointee(ImplSourcePointeeData) => &[],
+            | ImplSource::Pointee(ImplSourcePointeeData)
+            | ImplSource::ConstDrop(ImplSourceConstDropData) => &[],
             ImplSource::TraitAlias(d) => &d.nested[..],
             ImplSource::TraitUpcasting(d) => &d.nested[..],
         }
@@ -621,6 +636,9 @@ pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
                     nested: d.nested.into_iter().map(f).collect(),
                 })
             }
+            ImplSource::ConstDrop(ImplSourceConstDropData) => {
+                ImplSource::ConstDrop(ImplSourceConstDropData)
+            }
         }
     }
 }
@@ -712,6 +730,9 @@ pub struct ImplSourceFnPointerData<'tcx, N> {
 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub struct ImplSourcePointeeData;
 
+#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
+pub struct ImplSourceConstDropData;
+
 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceTraitAliasData<'tcx, N> {
     pub alias_def_id: DefId,
@@ -719,7 +740,7 @@ pub struct ImplSourceTraitAliasData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
 pub enum ObjectSafetyViolation {
     /// `Self: Sized` declared on the trait.
     SizedSelf(SmallVec<[Span; 1]>),
@@ -868,7 +889,7 @@ trait objects",
 }
 
 /// Reasons a method might not be object-safe.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
 pub enum MethodViolationCode {
     /// e.g., `fn foo()`
     StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
index 62996bf4cbef20cbabd6ac505afbde0533ad811b..3c0fedb360827ef9a0900f384afee996e3407ccf 100644 (file)
@@ -143,6 +143,9 @@ pub enum SelectionCandidate<'tcx> {
     BuiltinObjectCandidate,
 
     BuiltinUnsizeCandidate,
+
+    /// Implementation of `const Drop`.
+    ConstDropCandidate,
 }
 
 /// The result of trait evaluation. The order is important
index aa16e14fedcde9318c9a43bb29a75310b7de5da3..6032004e6077652a408506098dad933be5ba54d4 100644 (file)
@@ -32,6 +32,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
 
             super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
+
+            super::ImplSource::ConstDrop(ref d) => write!(f, "{:?}", d),
         }
     }
 }
@@ -125,4 +127,5 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     super::IfExpressionCause,
     super::ImplSourceDiscriminantKindData,
     super::ImplSourcePointeeData,
+    super::ImplSourceConstDropData,
 }
index 27927bcca72b7a6accc5a017c64f2ee5c68d0417..c32f0ea9ca55a2c147c9177071379f92960b6a92 100644 (file)
@@ -7,6 +7,7 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorReported;
+use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::{Idx, IndexVec};
@@ -288,6 +289,10 @@ pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
         self.destructor(tcx).is_some()
     }
 
+    pub fn has_non_const_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
+        matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. }))
+    }
+
     /// Asserts this is a struct or union and returns its unique variant.
     pub fn non_enum_variant(&self) -> &VariantDef {
         assert!(self.is_struct() || self.is_union());
index cd1e38445ae8c7a4c12194b5eb38ae79009e82ea..777c6035be831c503043aacd9e89ca503952979c 100644 (file)
@@ -1377,6 +1377,8 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
 pub struct Destructor {
     /// The `DefId` of the destructor method
     pub did: DefId,
+    /// The constness of the destructor method
+    pub constness: hir::Constness,
 }
 
 bitflags! {
index 8a2abb037579839342b8b99eb9cb9fc6622c7761..2ec06d472fee0b9889f33ff146c267d2ee707f82 100644 (file)
@@ -324,16 +324,16 @@ pub fn calculate_dtor(
         self.ensure().coherent_trait(drop_trait);
 
         let ty = self.type_of(adt_did);
-        let dtor_did = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
+        let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
             if let Some(item) = self.associated_items(impl_did).in_definition_order().next() {
                 if validate(self, impl_did).is_ok() {
-                    return Some(item.def_id);
+                    return Some((item.def_id, self.impl_constness(impl_did)));
                 }
             }
             None
-        });
+        })?;
 
-        Some(ty::Destructor { did: dtor_did? })
+        Some(ty::Destructor { did, constness })
     }
 
     /// Returns the set of types that are required to be alive in
index b34c1e07be71c61ff6d2673d67e1ea2bfe1509e6..4c51b9207bb750b03536b53de29c4183ec1aa2f7 100644 (file)
@@ -14,8 +14,9 @@
 use rustc_hir::{HirId, Pat};
 use rustc_middle::thir::PatKind;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
-use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
+use rustc_session::lint::builtin::{
+    BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
+};
 use rustc_session::Session;
 use rustc_span::{DesugaringKind, ExpnKind, Span};
 use std::slice;
@@ -559,7 +560,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     err.emit();
 }
 
-fn joined_uncovered_patterns(witnesses: &[super::Pat<'_>]) -> String {
+crate fn joined_uncovered_patterns(witnesses: &[super::Pat<'_>]) -> String {
     const LIMIT: usize = 3;
     match witnesses {
         [] => bug!(),
@@ -576,7 +577,7 @@ fn joined_uncovered_patterns(witnesses: &[super::Pat<'_>]) -> String {
     }
 }
 
-fn pattern_not_covered_label(witnesses: &[super::Pat<'_>], joined_patterns: &str) -> String {
+crate fn pattern_not_covered_label(witnesses: &[super::Pat<'_>], joined_patterns: &str) -> String {
     format!("pattern{} {} not covered", rustc_errors::pluralize!(witnesses.len()), joined_patterns)
 }
 
index ace13ea44624d627b8959b0328e7e8310d15ba68..cee2a4db0a8b3b6649bf487801d361f8ff97ca6f 100644 (file)
@@ -606,8 +606,9 @@ pub(super) enum Constructor<'tcx> {
     /// for those types for which we cannot list constructors explicitly, like `f64` and `str`.
     NonExhaustive,
     /// Stands for constructors that are not seen in the matrix, as explained in the documentation
-    /// for [`SplitWildcard`].
-    Missing,
+    /// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns`
+    /// lint.
+    Missing { nonexhaustive_enum_missing_real_variants: bool },
     /// Wildcard pattern.
     Wildcard,
 }
@@ -617,6 +618,10 @@ pub(super) fn is_wildcard(&self) -> bool {
         matches!(self, Wildcard)
     }
 
+    pub(super) fn is_non_exhaustive(&self) -> bool {
+        matches!(self, NonExhaustive)
+    }
+
     fn as_int_range(&self) -> Option<&IntRange> {
         match self {
             IntRange(range) => Some(range),
@@ -756,7 +761,7 @@ pub(super) fn is_covered_by<'p>(&self, pcx: PatCtxt<'_, 'p, 'tcx>, other: &Self)
             // Wildcards cover anything
             (_, Wildcard) => true,
             // The missing ctors are not covered by anything in the matrix except wildcards.
-            (Missing | Wildcard, _) => false,
+            (Missing { .. } | Wildcard, _) => false,
 
             (Single, Single) => true,
             (Variant(self_id), Variant(other_id)) => self_id == other_id,
@@ -829,7 +834,7 @@ fn is_covered_by_any<'p>(
                 .any(|other| slice.is_covered_by(other)),
             // This constructor is never covered by anything else
             NonExhaustive => false,
-            Str(..) | FloatRange(..) | Opaque | Missing | Wildcard => {
+            Str(..) | FloatRange(..) | Opaque | Missing { .. } | Wildcard => {
                 span_bug!(pcx.span, "found unexpected ctor in all_ctors: {:?}", self)
             }
         }
@@ -919,8 +924,14 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
                     && !cx.tcx.features().exhaustive_patterns
                     && !pcx.is_top_level;
 
-                if is_secretly_empty || is_declared_nonexhaustive {
+                if is_secretly_empty {
                     smallvec![NonExhaustive]
+                } else if is_declared_nonexhaustive {
+                    def.variants
+                        .indices()
+                        .map(|idx| Variant(idx))
+                        .chain(Some(NonExhaustive))
+                        .collect()
                 } else if cx.tcx.features().exhaustive_patterns {
                     // If `exhaustive_patterns` is enabled, we exclude variants known to be
                     // uninhabited.
@@ -975,6 +986,7 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
             // This type is one for which we cannot list constructors, like `str` or `f64`.
             _ => smallvec![NonExhaustive],
         };
+
         SplitWildcard { matrix_ctors: Vec::new(), all_ctors }
     }
 
@@ -1039,7 +1051,17 @@ pub(super) fn iter_missing<'a, 'p>(
             // sometimes prefer reporting the list of constructors instead of just `_`.
             let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(pcx.ty);
             let ctor = if !self.matrix_ctors.is_empty() || report_when_all_missing {
-                Missing
+                if pcx.is_non_exhaustive {
+                    Missing {
+                        nonexhaustive_enum_missing_real_variants: self
+                            .iter_missing(pcx)
+                            .filter(|c| !c.is_non_exhaustive())
+                            .next()
+                            .is_some(),
+                    }
+                } else {
+                    Missing { nonexhaustive_enum_missing_real_variants: false }
+                }
             } else {
                 Wildcard
             };
@@ -1176,7 +1198,12 @@ pub(super) fn wildcards(pcx: PatCtxt<'_, 'p, 'tcx>, constructor: &Constructor<'t
                 }
                 _ => bug!("bad slice pattern {:?} {:?}", constructor, ty),
             },
-            Str(..) | FloatRange(..) | IntRange(..) | NonExhaustive | Opaque | Missing
+            Str(..)
+            | FloatRange(..)
+            | IntRange(..)
+            | NonExhaustive
+            | Opaque
+            | Missing { .. }
             | Wildcard => Fields::Slice(&[]),
         };
         debug!("Fields::wildcards({:?}, {:?}) = {:#?}", constructor, ty, ret);
@@ -1189,15 +1216,18 @@ pub(super) fn wildcards(pcx: PatCtxt<'_, 'p, 'tcx>, constructor: &Constructor<'t
     /// This is roughly the inverse of `specialize_constructor`.
     ///
     /// Examples:
-    /// `ctor`: `Constructor::Single`
-    /// `ty`: `Foo(u32, u32, u32)`
-    /// `self`: `[10, 20, _]`
+    ///
+    /// ```text
+    /// ctor: `Constructor::Single`
+    /// ty: `Foo(u32, u32, u32)`
+    /// self: `[10, 20, _]`
     /// returns `Foo(10, 20, _)`
     ///
-    /// `ctor`: `Constructor::Variant(Option::Some)`
-    /// `ty`: `Option<bool>`
-    /// `self`: `[false]`
+    /// ctor: `Constructor::Variant(Option::Some)`
+    /// ty: `Option<bool>`
+    /// self: `[false]`
     /// returns `Some(false)`
+    /// ```
     pub(super) fn apply(self, pcx: PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'tcx>) -> Pat<'tcx> {
         let subpatterns_and_indices = self.patterns_and_indices();
         let mut subpatterns = subpatterns_and_indices.iter().map(|&(_, p)| p).cloned();
@@ -1265,7 +1295,7 @@ pub(super) fn apply(self, pcx: PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'tcx>)
             NonExhaustive => PatKind::Wild,
             Wildcard => return Pat::wildcard_from_ty(pcx.ty),
             Opaque => bug!("we should not try to apply an opaque constructor"),
-            Missing => bug!(
+            Missing { .. } => bug!(
                 "trying to apply the `Missing` constructor; this should have been done in `apply_constructors`"
             ),
         };
index 344006e9fb4c902af74703640f3b0036b968db12..f4255713e2a378bebca4e2c010c5c7b9447565c6 100644 (file)
 //! The details are not necessary to understand this file, so we explain them in
 //! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function.
 
+use self::ArmType::*;
 use self::Usefulness::*;
-use self::WitnessPreference::*;
 
+use super::check_match::{joined_uncovered_patterns, pattern_not_covered_label};
 use super::deconstruct_pat::{Constructor, Fields, SplitWildcard};
 use super::{PatternFoldable, PatternFolder};
 
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 
+use hir::def_id::DefId;
+use hir::HirId;
 use rustc_arena::TypedArena;
-use rustc_hir::def_id::DefId;
-use rustc_hir::HirId;
+use rustc_hir as hir;
 use rustc_middle::thir::{Pat, PatKind};
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::Span;
 
 use smallvec::{smallvec, SmallVec};
@@ -343,6 +346,8 @@ pub(super) struct PatCtxt<'a, 'p, 'tcx> {
     /// Whether the current pattern is the whole pattern as found in a match arm, or if it's a
     /// subpattern.
     pub(super) is_top_level: bool,
+    /// Wether the current pattern is from a `non_exhaustive` enum.
+    pub(super) is_non_exhaustive: bool,
 }
 
 impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
@@ -862,7 +867,7 @@ fn unsplit_or_pat(mut self, alt_id: usize, alt_count: usize, pat: &'p Pat<'tcx>)
 /// of potential unreachable sub-patterns (in the presence of or-patterns). When checking
 /// exhaustiveness of a whole match, we use the `WithWitnesses` variant, which carries a list of
 /// witnesses of non-exhaustiveness when there are any.
-/// Which variant to use is dictated by `WitnessPreference`.
+/// Which variant to use is dictated by `ArmType`.
 #[derive(Clone, Debug)]
 enum Usefulness<'p, 'tcx> {
     /// Carries a set of subpatterns that have been found to be reachable. If empty, this indicates
@@ -877,16 +882,24 @@ enum Usefulness<'p, 'tcx> {
 }
 
 impl<'p, 'tcx> Usefulness<'p, 'tcx> {
-    fn new_useful(preference: WitnessPreference) -> Self {
+    fn new_useful(preference: ArmType) -> Self {
         match preference {
-            ConstructWitness => WithWitnesses(vec![Witness(vec![])]),
-            LeaveOutWitness => NoWitnesses(SubPatSet::full()),
+            FakeExtraWildcard => WithWitnesses(vec![Witness(vec![])]),
+            RealArm => NoWitnesses(SubPatSet::full()),
         }
     }
-    fn new_not_useful(preference: WitnessPreference) -> Self {
+
+    fn new_not_useful(preference: ArmType) -> Self {
         match preference {
-            ConstructWitness => WithWitnesses(vec![]),
-            LeaveOutWitness => NoWitnesses(SubPatSet::empty()),
+            FakeExtraWildcard => WithWitnesses(vec![]),
+            RealArm => NoWitnesses(SubPatSet::empty()),
+        }
+    }
+
+    fn is_useful(&self) -> bool {
+        match self {
+            Usefulness::NoWitnesses(set) => !set.is_empty(),
+            Usefulness::WithWitnesses(witnesses) => !witnesses.is_empty(),
         }
     }
 
@@ -903,7 +916,7 @@ fn extend(&mut self, other: Self) {
 
     /// When trying several branches and each returns a `Usefulness`, we need to combine the
     /// results together.
-    fn merge(pref: WitnessPreference, usefulnesses: impl Iterator<Item = Self>) -> Self {
+    fn merge(pref: ArmType, usefulnesses: impl Iterator<Item = Self>) -> Self {
         let mut ret = Self::new_not_useful(pref);
         for u in usefulnesses {
             ret.extend(u);
@@ -926,7 +939,7 @@ fn unsplit_or_pat(self, alt_id: usize, alt_count: usize, pat: &'p Pat<'tcx>) ->
         }
     }
 
-    /// After calculating usefulness after a specialization, call this to recontruct a usefulness
+    /// After calculating usefulness after a specialization, call this to reconstruct a usefulness
     /// that makes sense for the matrix pre-specialization. This new usefulness can then be merged
     /// with the results of specializing with the other constructors.
     fn apply_constructor(
@@ -939,19 +952,31 @@ fn apply_constructor(
         match self {
             WithWitnesses(witnesses) if witnesses.is_empty() => WithWitnesses(witnesses),
             WithWitnesses(witnesses) => {
-                let new_witnesses = if matches!(ctor, Constructor::Missing) {
-                    let mut split_wildcard = SplitWildcard::new(pcx);
-                    split_wildcard.split(pcx, matrix.head_ctors(pcx.cx));
-                    // Construct for each missing constructor a "wild" version of this
-                    // constructor, that matches everything that can be built with
-                    // it. For example, if `ctor` is a `Constructor::Variant` for
-                    // `Option::Some`, we get the pattern `Some(_)`.
-                    let new_patterns: Vec<_> = split_wildcard
-                        .iter_missing(pcx)
-                        .map(|missing_ctor| {
-                            Fields::wildcards(pcx, missing_ctor).apply(pcx, missing_ctor)
-                        })
-                        .collect();
+                let new_witnesses = if let Constructor::Missing { .. } = ctor {
+                    // We got the special `Missing` constructor, so each of the missing constructors
+                    // gives a new pattern that is not caught by the match. We list those patterns.
+                    let new_patterns = if pcx.is_non_exhaustive {
+                        // Here we don't want the user to try to list all variants, we want them to add
+                        // a wildcard, so we only suggest that.
+                        vec![
+                            Fields::wildcards(pcx, &Constructor::NonExhaustive)
+                                .apply(pcx, &Constructor::NonExhaustive),
+                        ]
+                    } else {
+                        let mut split_wildcard = SplitWildcard::new(pcx);
+                        split_wildcard.split(pcx, matrix.head_ctors(pcx.cx));
+                        // Construct for each missing constructor a "wild" version of this
+                        // constructor, that matches everything that can be built with
+                        // it. For example, if `ctor` is a `Constructor::Variant` for
+                        // `Option::Some`, we get the pattern `Some(_)`.
+                        split_wildcard
+                            .iter_missing(pcx)
+                            .map(|missing_ctor| {
+                                Fields::wildcards(pcx, missing_ctor).apply(pcx, missing_ctor)
+                            })
+                            .collect()
+                    };
+
                     witnesses
                         .into_iter()
                         .flat_map(|witness| {
@@ -976,9 +1001,9 @@ fn apply_constructor(
 }
 
 #[derive(Copy, Clone, Debug)]
-enum WitnessPreference {
-    ConstructWitness,
-    LeaveOutWitness,
+enum ArmType {
+    FakeExtraWildcard,
+    RealArm,
 }
 
 /// A witness of non-exhaustiveness for error reporting, represented
@@ -1056,6 +1081,32 @@ fn apply_constructor<'p>(
     }
 }
 
+/// Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
+/// is not exhaustive enough.
+///
+/// NB: The partner lint for structs lives in `compiler/rustc_typeck/src/check/pat.rs`.
+fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
+    cx: &MatchCheckCtxt<'p, 'tcx>,
+    scrut_ty: Ty<'tcx>,
+    sp: Span,
+    hir_id: HirId,
+    witnesses: Vec<Pat<'tcx>>,
+) {
+    let joined_patterns = joined_uncovered_patterns(&witnesses);
+    cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, |build| {
+        let mut lint = build.build("some variants are not matched explicitly");
+        lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
+        lint.help(
+            "ensure that all variants are matched explicitly by adding the suggested match arms",
+        );
+        lint.note(&format!(
+            "the matched value is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
+            scrut_ty,
+        ));
+        lint.emit();
+    });
+}
+
 /// Algorithm from <http://moscova.inria.fr/~maranget/papers/warn/index.html>.
 /// The algorithm from the paper has been modified to correctly handle empty
 /// types. The changes are:
@@ -1086,7 +1137,7 @@ fn is_useful<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
     matrix: &Matrix<'p, 'tcx>,
     v: &PatStack<'p, 'tcx>,
-    witness_preference: WitnessPreference,
+    witness_preference: ArmType,
     hir_id: HirId,
     is_under_guard: bool,
     is_top_level: bool,
@@ -1113,7 +1164,8 @@ fn is_useful<'p, 'tcx>(
 
     // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
     let ty = matrix.heads().next().map_or(v.head().ty, |r| r.ty);
-    let pcx = PatCtxt { cx, ty, span: v.head().span, is_top_level };
+    let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty);
+    let pcx = PatCtxt { cx, ty, span: v.head().span, is_top_level, is_non_exhaustive };
 
     // If the first pattern is an or-pattern, expand it.
     let ret = if is_or_pat(v.head()) {
@@ -1148,6 +1200,7 @@ fn is_useful<'p, 'tcx>(
         }
         // We split the head constructor of `v`.
         let split_ctors = v_ctor.split(pcx, matrix.head_ctors(cx));
+        let is_non_exhaustive_and_wild = is_non_exhaustive && v_ctor.is_wildcard();
         // For each constructor, we compute whether there's a value that starts with it that would
         // witness the usefulness of `v`.
         let start_matrix = &matrix;
@@ -1160,10 +1213,46 @@ fn is_useful<'p, 'tcx>(
             let v = v.pop_head_constructor(&ctor_wild_subpatterns);
             let usefulness =
                 is_useful(cx, &spec_matrix, &v, witness_preference, hir_id, is_under_guard, false);
+
+            // When all the conditions are met we have a match with a `non_exhaustive` enum
+            // that has the potential to trigger the `non_exhaustive_omitted_patterns` lint.
+            // To understand the workings checkout `Constructor::split` and `SplitWildcard::new/into_ctors`
+            if is_non_exhaustive_and_wild
+                // We check that the match has a wildcard pattern and that that wildcard is useful,
+                // meaning there are variants that are covered by the wildcard. Without the check
+                // for `witness_preference` the lint would trigger on `if let NonExhaustiveEnum::A = foo {}`
+                && usefulness.is_useful() && matches!(witness_preference, RealArm)
+                && matches!(
+                    &ctor,
+                    Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
+                )
+            {
+                let patterns = {
+                    let mut split_wildcard = SplitWildcard::new(pcx);
+                    split_wildcard.split(pcx, matrix.head_ctors(pcx.cx));
+                    // Construct for each missing constructor a "wild" version of this
+                    // constructor, that matches everything that can be built with
+                    // it. For example, if `ctor` is a `Constructor::Variant` for
+                    // `Option::Some`, we get the pattern `Some(_)`.
+                    split_wildcard
+                        .iter_missing(pcx)
+                        // Filter out the `Constructor::NonExhaustive` variant it's meaningless
+                        // to our lint
+                        .filter(|c| !c.is_non_exhaustive())
+                        .map(|missing_ctor| {
+                            Fields::wildcards(pcx, missing_ctor).apply(pcx, missing_ctor)
+                        })
+                        .collect::<Vec<_>>()
+                };
+
+                lint_non_exhaustive_omitted_patterns(pcx.cx, pcx.ty, pcx.span, hir_id, patterns);
+            }
+
             usefulness.apply_constructor(pcx, start_matrix, &ctor, &ctor_wild_subpatterns)
         });
         Usefulness::merge(witness_preference, usefulnesses)
     };
+
     debug!(?ret);
     ret
 }
@@ -1214,8 +1303,7 @@ fn is_useful<'p, 'tcx>(
         .copied()
         .map(|arm| {
             let v = PatStack::from_pattern(arm.pat);
-            let usefulness =
-                is_useful(cx, &matrix, &v, LeaveOutWitness, arm.hir_id, arm.has_guard, true);
+            let usefulness = is_useful(cx, &matrix, &v, RealArm, arm.hir_id, arm.has_guard, true);
             if !arm.has_guard {
                 matrix.push(v);
             }
@@ -1232,7 +1320,7 @@ fn is_useful<'p, 'tcx>(
 
     let wild_pattern = cx.pattern_arena.alloc(Pat::wildcard_from_ty(scrut_ty));
     let v = PatStack::from_pattern(wild_pattern);
-    let usefulness = is_useful(cx, &matrix, &v, ConstructWitness, scrut_hir_id, false, true);
+    let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, scrut_hir_id, false, true);
     let non_exhaustiveness_witnesses = match usefulness {
         WithWitnesses(pats) => pats.into_iter().map(|w| w.single_pattern()).collect(),
         NoWitnesses(_) => bug!(),
index bfae09b7760a04672941a8c63d962fbe31ea2d03..72c4e27cbeabfbcffd5b98f98810512604e31d3f 100644 (file)
@@ -28,8 +28,8 @@
     on_lookup_result_bits,
 };
 pub use self::framework::{
-    fmt, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, Forward,
-    GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor,
+    fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine,
+    Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor,
     ResultsVisitable, ResultsVisitor,
 };
 
index 90d7cbee976d0d1dcbcec069bcb6eb627da1eb9f..bfd0de85438d1044778c9e142601abf61317e64d 100644 (file)
@@ -76,7 +76,7 @@
 use rustc_const_eval::transform::check_consts;
 use rustc_const_eval::transform::promote_consts;
 use rustc_const_eval::transform::validate;
-use rustc_const_eval::transform::MirPass;
+pub use rustc_const_eval::transform::MirPass;
 use rustc_mir_dataflow::rustc_peek;
 
 pub fn provide(providers: &mut Providers) {
index 25e3c52132cca69b59c30d44f719d9298bb07f47..d93ffa38c69066f40a5cced0b7bcf479b6993cea 100644 (file)
@@ -9,6 +9,10 @@
 
 impl<'tcx> MirPass<'tcx> for RemoveZsts {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        // Avoid query cycles (generators require optimized MIR for layout).
+        if tcx.type_of(body.source.def_id()).is_generator() {
+            return;
+        }
         let param_env = tcx.param_env(body.source.def_id());
         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
         for block in basic_blocks.iter_mut() {
index 3c55a4b0a8fb1e52040d7a3e6055c2aeb47921d9..0f768b7819b5b67e35e6938626b5347e27588be3 100644 (file)
@@ -30,7 +30,7 @@ pub fn provide(providers: &mut Providers) {
 /// Determine which generic parameters are used by the function/method/closure represented by
 /// `def_id`. Returns a bitset where bits representing unused parameters are set (`is_empty`
 /// indicates all parameters are used).
-#[instrument(skip(tcx))]
+#[instrument(level = "debug", skip(tcx))]
 fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
     if !tcx.sess.opts.debugging_opts.polymorphize {
         // If polymorphization disabled, then all parameters are used.
@@ -100,7 +100,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
 /// Some parameters are considered used-by-default, such as non-generic parameters and the dummy
 /// generic parameters from closures, this function marks them as used. `leaf_is_closure` should
 /// be `true` if the item that `unused_generic_params` was invoked on is a closure.
-#[instrument(skip(tcx, def_id, generics, unused_parameters))]
+#[instrument(level = "debug", skip(tcx, def_id, generics, unused_parameters))]
 fn mark_used_by_default_parameters<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
@@ -158,7 +158,7 @@ fn mark_used_by_default_parameters<'tcx>(
 
 /// Search the predicates on used generic parameters for any unused generic parameters, and mark
 /// those as used.
-#[instrument(skip(tcx, def_id))]
+#[instrument(level = "debug", skip(tcx, def_id))]
 fn mark_used_by_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
@@ -196,7 +196,7 @@ fn mark_used_by_predicates<'tcx>(
 
 /// Emit errors for the function annotated by `#[rustc_polymorphize_error]`, labelling each generic
 /// parameter which was unused.
-#[instrument(skip(tcx, generics))]
+#[instrument(level = "debug", skip(tcx, generics))]
 fn emit_unused_generic_params_error<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
@@ -241,7 +241,7 @@ struct MarkUsedGenericParams<'a, 'tcx> {
 impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
     /// Invoke `unused_generic_params` on a body contained within the current item (e.g.
     /// a closure, generator or constant).
-    #[instrument(skip(self, def_id, substs))]
+    #[instrument(level = "debug", skip(self, def_id, substs))]
     fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
         let unused = self.tcx.unused_generic_params(def_id);
         debug!(?self.unused_parameters, ?unused);
@@ -256,7 +256,7 @@ fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
-    #[instrument(skip(self, local))]
+    #[instrument(level = "debug", skip(self, local))]
     fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
         if local == Local::from_usize(1) {
             let def_kind = self.tcx.def_kind(self.def_id);
@@ -286,7 +286,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
     fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
         Some(self.tcx)
     }
-    #[instrument(skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
         if !c.potentially_has_param_types_or_consts() {
             return ControlFlow::CONTINUE;
@@ -319,7 +319,7 @@ fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
         }
     }
 
-    #[instrument(skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         if !ty.potentially_has_param_types_or_consts() {
             return ControlFlow::CONTINUE;
@@ -361,7 +361,7 @@ fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
         Some(self.tcx)
     }
 
-    #[instrument(skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
         if !c.potentially_has_param_types_or_consts() {
             return ControlFlow::CONTINUE;
@@ -379,7 +379,7 @@ fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
         }
     }
 
-    #[instrument(skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         if !ty.potentially_has_param_types_or_consts() {
             return ControlFlow::CONTINUE;
index 4fccfc287fd82e1aed8ee213201fbde7c59a28f8..708df5e46d4e22ef94dca8c3bdd49f61a8f53800 100644 (file)
@@ -1334,30 +1334,25 @@ pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
     pub(super) fn recover_parens_around_for_head(
         &mut self,
         pat: P<Pat>,
-        expr: &Expr,
         begin_paren: Option<Span>,
     ) -> P<Pat> {
         match (&self.token.kind, begin_paren) {
             (token::CloseDelim(token::Paren), Some(begin_par_sp)) => {
                 self.bump();
 
-                let pat_str = self
-                    // Remove the `(` from the span of the pattern:
-                    .span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap())
-                    .unwrap_or_else(|_| pprust::pat_to_string(&pat));
-
-                self.struct_span_err(self.prev_token.span, "unexpected closing `)`")
-                    .span_label(begin_par_sp, "opening `(`")
-                    .span_suggestion(
-                        begin_par_sp.to(self.prev_token.span),
-                        "remove parenthesis in `for` loop",
-                        format!("{} in {}", pat_str, pprust::expr_to_string(&expr)),
-                        // With e.g. `for (x) in y)` this would replace `(x) in y)`
-                        // with `x) in y)` which is syntactically invalid.
-                        // However, this is prevented before we get here.
-                        Applicability::MachineApplicable,
-                    )
-                    .emit();
+                self.struct_span_err(
+                    MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]),
+                    "unexpected parenthesis surrounding `for` loop head",
+                )
+                .multipart_suggestion(
+                    "remove parenthesis in `for` loop",
+                    vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())],
+                    // With e.g. `for (x) in y)` this would replace `(x) in y)`
+                    // with `x) in y)` which is syntactically invalid.
+                    // However, this is prevented before we get here.
+                    Applicability::MachineApplicable,
+                )
+                .emit();
 
                 // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
                 pat.and_then(|pat| match pat.kind {
@@ -1955,7 +1950,19 @@ pub fn recover_const_arg(
         }
         match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
             Ok(expr) => {
-                if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() {
+                // Find a mistake like `MyTrait<Assoc == S::Assoc>`.
+                if token::EqEq == snapshot.token.kind {
+                    err.span_suggestion(
+                        snapshot.token.span,
+                        "if you meant to use an associated type binding, replace `==` with `=`",
+                        "=".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                    let value = self.mk_expr_err(start.to(expr.span));
+                    err.emit();
+                    return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
+                } else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
+                {
                     // Avoid the following output by checking that we consumed a full const arg:
                     // help: expressions must be enclosed in braces to be used as const generic
                     //       arguments
index dc80dab8c6c5f9d55f4c480a1ae932966fd74141..d8f9fc9179e890e9a6a012e7a81f16577184882c 100644 (file)
@@ -907,6 +907,12 @@ fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<
         }
     }
 
+    fn look_ahead_type_ascription_as_field(&mut self) -> bool {
+        self.look_ahead(1, |t| t.is_ident())
+            && self.look_ahead(2, |t| t == &token::Colon)
+            && self.look_ahead(3, |t| t.can_begin_expr())
+    }
+
     fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
         match self.token.uninterpolate().kind {
             token::Ident(..) => self.parse_dot_suffix(base, lo),
@@ -1056,12 +1062,76 @@ fn parse_tuple_field_access_expr(
 
     /// Parse a function call expression, `expr(...)`.
     fn parse_fn_call_expr(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
-        let seq = self.parse_paren_expr_seq().map(|args| {
+        let snapshot = if self.token.kind == token::OpenDelim(token::Paren)
+            && self.look_ahead_type_ascription_as_field()
+        {
+            Some((self.clone(), fun.kind.clone()))
+        } else {
+            None
+        };
+        let open_paren = self.token.span;
+
+        let mut seq = self.parse_paren_expr_seq().map(|args| {
             self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new())
         });
+        if let Some(expr) =
+            self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
+        {
+            return expr;
+        }
         self.recover_seq_parse_error(token::Paren, lo, seq)
     }
 
+    /// 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.
+    fn maybe_recover_struct_lit_bad_delims(
+        &mut self,
+        lo: Span,
+        open_paren: Span,
+        seq: &mut PResult<'a, P<Expr>>,
+        snapshot: Option<(Self, ExprKind)>,
+    ) -> Option<P<Expr>> {
+        match (seq.as_mut(), snapshot) {
+            (Err(ref mut err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
+                let name = pprust::path_to_string(&path);
+                snapshot.bump(); // `(`
+                match snapshot.parse_struct_fields(path.clone(), false, token::Paren) {
+                    Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
+                        // We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
+                        // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
+                        *self = snapshot;
+                        let close_paren = self.prev_token.span;
+                        let span = lo.to(self.prev_token.span);
+                        err.cancel();
+                        self.struct_span_err(
+                            span,
+                            "invalid `struct` delimiters or `fn` call arguments",
+                        )
+                        .multipart_suggestion(
+                            &format!("if `{}` is a struct, use braces as delimiters", name),
+                            vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())],
+                            Applicability::MaybeIncorrect,
+                        )
+                        .multipart_suggestion(
+                            &format!("if `{}` is a function, use the arguments directly", name),
+                            fields
+                                .into_iter()
+                                .map(|field| (field.span.until(field.expr.span), String::new()))
+                                .collect(),
+                            Applicability::MaybeIncorrect,
+                        )
+                        .emit();
+                        return Some(self.mk_expr_err(span));
+                    }
+                    Ok(_) => {}
+                    Err(mut err) => err.emit(),
+                }
+            }
+            _ => {}
+        }
+        None
+    }
+
     /// Parse an indexing expression `expr[...]`.
     fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
         self.bump(); // `[`
@@ -1972,7 +2042,7 @@ fn parse_for_expr(
         self.check_for_for_in_in_typo(self.prev_token.span);
         let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
 
-        let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren);
+        let pat = self.recover_parens_around_for_head(pat, begin_paren);
 
         let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
         attrs.extend(iattrs);
@@ -2374,14 +2444,12 @@ fn error_struct_lit_not_allowed_here(&self, lo: Span, sp: Span) {
             .emit();
     }
 
-    /// Precondition: already parsed the '{'.
-    pub(super) fn parse_struct_expr(
+    pub(super) fn parse_struct_fields(
         &mut self,
-        qself: Option<ast::QSelf>,
         pth: ast::Path,
-        attrs: AttrVec,
         recover: bool,
-    ) -> PResult<'a, P<Expr>> {
+        close_delim: token::DelimToken,
+    ) -> PResult<'a, (Vec<ExprField>, ast::StructRest, bool)> {
         let mut fields = Vec::new();
         let mut base = ast::StructRest::None;
         let mut recover_async = false;
@@ -2393,11 +2461,11 @@ pub(super) fn parse_struct_expr(
             e.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
         };
 
-        while self.token != token::CloseDelim(token::Brace) {
+        while self.token != token::CloseDelim(close_delim) {
             if self.eat(&token::DotDot) {
                 let exp_span = self.prev_token.span;
                 // We permit `.. }` on the left-hand side of a destructuring assignment.
-                if self.check(&token::CloseDelim(token::Brace)) {
+                if self.check(&token::CloseDelim(close_delim)) {
                     self.sess.gated_spans.gate(sym::destructuring_assignment, self.prev_token.span);
                     base = ast::StructRest::Rest(self.prev_token.span.shrink_to_hi());
                     break;
@@ -2438,7 +2506,7 @@ pub(super) fn parse_struct_expr(
                 }
             };
 
-            match self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) {
+            match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) {
                 Ok(_) => {
                     if let Some(f) = parsed_field.or(recovery_field) {
                         // Only include the field if there's no parse error for the field name.
@@ -2469,8 +2537,21 @@ pub(super) fn parse_struct_expr(
                 }
             }
         }
+        Ok((fields, base, recover_async))
+    }
 
-        let span = pth.span.to(self.token.span);
+    /// Precondition: already parsed the '{'.
+    pub(super) fn parse_struct_expr(
+        &mut self,
+        qself: Option<ast::QSelf>,
+        pth: ast::Path,
+        attrs: AttrVec,
+        recover: bool,
+    ) -> PResult<'a, P<Expr>> {
+        let lo = pth.span;
+        let (fields, base, recover_async) =
+            self.parse_struct_fields(pth.clone(), recover, token::Brace)?;
+        let span = lo.to(self.token.span);
         self.expect(&token::CloseDelim(token::Brace))?;
         let expr = if recover_async {
             ExprKind::Err
index 10c73fd64bc198cece7158a1ea964629b8d985d8..0e2222bf84093913d3bfc926621130452c7ac6fd 100644 (file)
@@ -493,7 +493,20 @@ fn parse_item_impl(
         let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
         {
             let span = self.prev_token.span.between(self.token.span);
-            self.struct_span_err(span, "missing trait in a trait impl").emit();
+            self.struct_span_err(span, "missing trait in a trait impl")
+                .span_suggestion(
+                    span,
+                    "add a trait here",
+                    " Trait ".into(),
+                    Applicability::HasPlaceholders,
+                )
+                .span_suggestion(
+                    span.to(self.token.span),
+                    "for an inherent impl, drop this `for`",
+                    "".into(),
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
             P(Ty {
                 kind: TyKind::Path(None, err_path(span)),
                 span,
@@ -1234,7 +1247,7 @@ fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
         Ok((class_name, ItemKind::Union(vdata, generics)))
     }
 
-    pub(super) fn parse_record_struct_body(
+    fn parse_record_struct_body(
         &mut self,
         adt_ty: &str,
     ) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
@@ -1468,28 +1481,22 @@ fn parse_name_and_ty(
     fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
         let (ident, is_raw) = self.ident_or_err()?;
         if !is_raw && ident.is_reserved() {
-            if ident.name == kw::Underscore {
-                self.sess.gated_spans.gate(sym::unnamed_fields, lo);
+            let err = if self.check_fn_front_matter(false) {
+                // We use `parse_fn` to get a span for the function
+                if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) {
+                    db.delay_as_bug();
+                }
+                let mut err = self.struct_span_err(
+                    lo.to(self.prev_token.span),
+                    &format!("functions are not allowed in {} definitions", adt_ty),
+                );
+                err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
+                err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
+                err
             } else {
-                let err = if self.check_fn_front_matter(false) {
-                    // We use `parse_fn` to get a span for the function
-                    if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) {
-                        db.delay_as_bug();
-                    }
-                    let mut err = self.struct_span_err(
-                        lo.to(self.prev_token.span),
-                        &format!("functions are not allowed in {} definitions", adt_ty),
-                    );
-                    err.help(
-                        "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
-                    );
-                    err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
-                    err
-                } else {
-                    self.expected_ident_found()
-                };
-                return Err(err);
-            }
+                self.expected_ident_found()
+            };
+            return Err(err);
         }
         self.bump();
         Ok(ident)
index 25dcb4a112de1c7e030498a7167e97be22526055..9ec6effeb4e03a9e2ed2368204ed75511a38eb3d 100644 (file)
@@ -155,17 +155,20 @@ fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResu
 
         let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
 
-        let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof
-        {
-            StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
-        } else {
-            // Since none of the above applied, this is an expression statement macro.
-            let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
-            let e = self.maybe_recover_from_bad_qpath(e, true)?;
-            let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
-            let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
-            StmtKind::Expr(e)
-        };
+        let kind =
+            if (delim == token::Brace && self.token != token::Dot && self.token != token::Question)
+                || self.token == token::Semi
+                || self.token == token::Eof
+            {
+                StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
+            } else {
+                // Since none of the above applied, this is an expression statement macro.
+                let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
+                let e = self.maybe_recover_from_bad_qpath(e, true)?;
+                let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
+                let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
+                StmtKind::Expr(e)
+            };
         Ok(self.mk_stmt(lo.to(hi), kind))
     }
 
index 299fc916ac97fa7802b2f6a6865877dc8a0744e7..98400372c36a6576e9c90b8350f2d430d52a6a20 100644 (file)
@@ -226,19 +226,6 @@ fn parse_ty_common(
             }
         } else if self.eat_keyword(kw::Impl) {
             self.parse_impl_ty(&mut impl_dyn_multi)?
-        } else if self.token.is_keyword(kw::Union)
-            && self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
-        {
-            self.bump();
-            let (fields, recovered) = self.parse_record_struct_body("union")?;
-            let span = lo.to(self.prev_token.span);
-            self.sess.gated_spans.gate(sym::unnamed_fields, span);
-            TyKind::AnonymousUnion(fields, recovered)
-        } else if self.eat_keyword(kw::Struct) {
-            let (fields, recovered) = self.parse_record_struct_body("struct")?;
-            let span = lo.to(self.prev_token.span);
-            self.sess.gated_spans.gate(sym::unnamed_fields, span);
-            TyKind::AnonymousStruct(fields, recovered)
         } else if self.is_explicit_dyn_type() {
             self.parse_dyn_ty(&mut impl_dyn_multi)?
         } else if self.eat_lt() {
index b7e43b7785da602a170632beddb3ad53f0083155..d7c354aeb490f6accc78a15593b84410dc3655f5 100644 (file)
@@ -929,6 +929,16 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     let declared_lib_features = &tcx.features().declared_lib_features;
     let mut remaining_lib_features = FxHashMap::default();
     for (feature, span) in declared_lib_features {
+        if !tcx.sess.opts.unstable_features.is_nightly_build() {
+            struct_span_err!(
+                tcx.sess,
+                *span,
+                E0554,
+                "`#![feature]` may not be used on the {} release channel",
+                env!("CFG_RELEASE_CHANNEL")
+            )
+            .emit();
+        }
         if remaining_lib_features.contains_key(&feature) {
             // Warn if the user enables a lib feature multiple times.
             duplicate_feature_err(tcx.sess, *span, *feature);
index 73c00fc49ba39c7794becf632ae0a8d1a9daa973..f5f67fcd0a08c322d3daca93e7ac299ef55a8ed4 100644 (file)
@@ -99,7 +99,7 @@ pub fn node_count(&self) -> usize {
 impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<'a>>
     for SerializedDepGraph<K>
 {
-    #[instrument(skip(d))]
+    #[instrument(level = "debug", skip(d))]
     fn decode(d: &mut opaque::Decoder<'a>) -> Result<SerializedDepGraph<K>, String> {
         let start_position = d.position();
 
@@ -187,7 +187,7 @@ fn new(encoder: FileEncoder, record_stats: bool) -> Self {
         }
     }
 
-    #[instrument(skip(self, record_graph))]
+    #[instrument(level = "debug", skip(self, record_graph))]
     fn encode_node(
         &mut self,
         node: &NodeInfo<K>,
index 4c1d537d55fa37cd3231337c248630f6f5e48ec3..a5dbbffeaa86beff97c88d9f73393212a521c471 100644 (file)
@@ -2024,7 +2024,7 @@ fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
         // ensure that we issue lints in a repeatable order
         def_ids.sort_by_cached_key(|&def_id| self.tcx.def_path_hash(def_id));
 
-        for def_id in def_ids {
+        'lifetimes: for def_id in def_ids {
             debug!("check_uses_for_lifetimes_defined_by_scope: def_id = {:?}", def_id);
 
             let lifetimeuseset = self.lifetime_uses.remove(&def_id);
@@ -2067,6 +2067,27 @@ fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
                                 {
                                     continue;
                                 }
+
+                                // opaque types generated when desugaring an async function can have a single
+                                // use lifetime even if it is explicitly denied (Issue #77175)
+                                if let hir::Node::Item(hir::Item {
+                                    kind: hir::ItemKind::OpaqueTy(ref opaque),
+                                    ..
+                                }) = self.tcx.hir().get(parent_hir_id)
+                                {
+                                    if opaque.origin != hir::OpaqueTyOrigin::AsyncFn {
+                                        continue 'lifetimes;
+                                    }
+                                    // We want to do this only if the liftime identifier is already defined
+                                    // in the async function that generated this. Otherwise it could be
+                                    // an opaque type defined by the developer and we still want this
+                                    // lint to fail compilation
+                                    for p in opaque.generics.params {
+                                        if defined_by.contains_key(&p.name) {
+                                            continue 'lifetimes;
+                                        }
+                                    }
+                                }
                             }
                         }
 
index fdedb7e6a4afe9b2334822fd8afcf0d576f5e0cf..32aa035e1cdecb458faea87ceba51e2f3938c84a 100644 (file)
@@ -1920,9 +1920,10 @@ fn parse_extern_dep_specs(
 
 fn parse_remap_path_prefix(
     matches: &getopts::Matches,
+    debugging_opts: &DebuggingOptions,
     error_format: ErrorOutputType,
 ) -> Vec<(PathBuf, PathBuf)> {
-    matches
+    let mut mapping: Vec<(PathBuf, PathBuf)> = matches
         .opt_strs("remap-path-prefix")
         .into_iter()
         .map(|remap| match remap.rsplit_once('=') {
@@ -1932,7 +1933,15 @@ fn parse_remap_path_prefix(
             ),
             Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
         })
-        .collect()
+        .collect();
+    match &debugging_opts.remap_cwd_prefix {
+        Some(to) => match std::env::current_dir() {
+            Ok(cwd) => mapping.push((cwd, to.clone())),
+            Err(_) => (),
+        },
+        None => (),
+    };
+    mapping
 }
 
 pub fn build_session_options(matches: &getopts::Matches) -> Options {
@@ -2077,7 +2086,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let crate_name = matches.opt_str("crate-name");
 
-    let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
+    let remap_path_prefix = parse_remap_path_prefix(matches, &debugging_opts, error_format);
 
     let pretty = parse_pretty(&debugging_opts, error_format);
 
index 6fe6a555f1af81ccf8f5c6b87039af4bf3ce5a65..9359a55e55a9c74845c6a539f30abb43b3016056 100644 (file)
@@ -1,3 +1,5 @@
+//! A module for searching for libraries
+
 pub use self::FileMatch::*;
 
 use std::env;
@@ -14,8 +16,6 @@ pub enum FileMatch {
     FileDoesntMatch,
 }
 
-// A module for searching for libraries
-
 #[derive(Clone)]
 pub struct FileSearch<'a> {
     sysroot: &'a Path,
@@ -83,22 +83,10 @@ pub fn new(
         FileSearch { sysroot, triple, search_paths, tlib_path, kind }
     }
 
-    // Returns just the directories within the search paths.
+    /// Returns just the directories within the search paths.
     pub fn search_path_dirs(&self) -> Vec<PathBuf> {
         self.search_paths().map(|sp| sp.dir.to_path_buf()).collect()
     }
-
-    // Returns a list of directories where target-specific tool binaries are located.
-    pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
-        let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple);
-        let p = std::array::IntoIter::new([
-            Path::new(&self.sysroot),
-            Path::new(&rustlib_path),
-            Path::new("bin"),
-        ])
-        .collect::<PathBuf>();
-        if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
-    }
 }
 
 pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
@@ -107,8 +95,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
         .collect::<PathBuf>()
 }
 
-// This function checks if sysroot is found using env::args().next(), and if it
-// is not found, uses env::current_exe() to imply sysroot.
+/// This function checks if sysroot is found using env::args().next(), and if it
+/// is not found, uses env::current_exe() to imply sysroot.
 pub fn get_or_default_sysroot() -> PathBuf {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: PathBuf) -> PathBuf {
index bb29a87035e8001f2e24b160a11ed4dbc3dbd977..8110afe75fa92969fb1364a06f748643d2c656ee 100644 (file)
@@ -1250,6 +1250,8 @@ mod parse {
         "whether ELF relocations can be relaxed"),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
         "choose which RELRO level to use"),
+    remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
+        "remap paths under the current working directory to this path prefix"),
     simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
         to rust's source base directory. only meant for testing purposes"),
index 83b737a73b1e84239a9d5ea1c33cb56e563aede7..acb6c735e051ebc2cfb90b5310e07c7bc8208533 100644 (file)
@@ -9,17 +9,17 @@ pub struct SearchPath {
     pub files: Vec<SearchPathFile>,
 }
 
-// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
-// it is searched repeatedly by `find_library_crate`, and the searches involve
-// checking the prefix and suffix of the filename of each `PathBuf`. This is
-// doable, but very slow, because it involves calls to `file_name` and
-// `extension` that are themselves slow.
-//
-// This type augments the `PathBuf` with an `Option<String>` containing the
-// `PathBuf`'s filename. The prefix and suffix checking is much faster on the
-// `Option<String>` than the `PathBuf`. (It's an `Option` because
-// `Path::file_name` can fail; if that happens then all subsequent checking
-// will also fail, which is fine.)
+/// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
+/// it is searched repeatedly by `find_library_crate`, and the searches involve
+/// checking the prefix and suffix of the filename of each `PathBuf`. This is
+/// doable, but very slow, because it involves calls to `file_name` and
+/// `extension` that are themselves slow.
+///
+/// This type augments the `PathBuf` with an `Option<String>` containing the
+/// `PathBuf`'s filename. The prefix and suffix checking is much faster on the
+/// `Option<String>` than the `PathBuf`. (It's an `Option` because
+/// `Path::file_name` can fail; if that happens then all subsequent checking
+/// will also fail, which is fine.)
 #[derive(Clone, Debug)]
 pub struct SearchPathFile {
     pub path: PathBuf,
index 4471e1e0ae8b46b7b3534a1407b2054c3fe3275f..d6f4a3ae4f121f76a8594e7662a224f7d057ce79 100644 (file)
@@ -36,7 +36,7 @@
 use std::io::Write;
 use std::num::NonZeroU32;
 use std::ops::{Div, Mul};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::sync::Arc;
 use std::time::Duration;
@@ -131,9 +131,8 @@ pub struct Session {
     pub target: Target,
     pub host: Target,
     pub opts: config::Options,
-    pub host_tlib_path: SearchPath,
-    /// `None` if the host and target are the same.
-    pub target_tlib_path: Option<SearchPath>,
+    pub host_tlib_path: Lrc<SearchPath>,
+    pub target_tlib_path: Lrc<SearchPath>,
     pub parse_sess: ParseSess,
     pub sysroot: PathBuf,
     /// The name of the root source file of the crate, in the local file system.
@@ -787,8 +786,7 @@ pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
             &self.sysroot,
             self.opts.target_triple.triple(),
             &self.opts.search_paths,
-            // `target_tlib_path == None` means it's the same as `host_tlib_path`.
-            self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path),
+            &self.target_tlib_path,
             kind,
         )
     }
@@ -802,6 +800,18 @@ pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
         )
     }
 
+    /// Returns a list of directories where target-specific tool binaries are located.
+    pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
+        let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, &config::host_triple());
+        let p = std::array::IntoIter::new([
+            Path::new(&self.sysroot),
+            Path::new(&rustlib_path),
+            Path::new("bin"),
+        ])
+        .collect::<PathBuf>();
+        if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
+    }
+
     pub fn init_incr_comp_session(
         &self,
         session_dir: PathBuf,
@@ -1245,11 +1255,13 @@ pub fn build_session(
 
     let host_triple = config::host_triple();
     let target_triple = sopts.target_triple.triple();
-    let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple);
+    let host_tlib_path = Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple));
     let target_tlib_path = if host_triple == target_triple {
-        None
+        // Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
+        // rescanning of the target lib path and an unnecessary allocation.
+        host_tlib_path.clone()
     } else {
-        Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
+        Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
     };
 
     let file_path_mapping = sopts.file_path_mapping();
index eb496140553ad80619d0a3bd0784c99db7cad80d..9c5469f635f71ee8c3f6d136d9b60f19242ea749 100644 (file)
@@ -78,7 +78,7 @@
 // threads within the compilation session, but is not accessible outside the
 // session.
 pub struct SessionGlobals {
-    symbol_interner: Lock<symbol::Interner>,
+    symbol_interner: symbol::Interner,
     span_interner: Lock<span_encoding::SpanInterner>,
     hygiene_data: Lock<hygiene::HygieneData>,
     source_map: Lock<Option<Lrc<SourceMap>>>,
@@ -87,7 +87,7 @@ pub struct SessionGlobals {
 impl SessionGlobals {
     pub fn new(edition: Edition) -> SessionGlobals {
         SessionGlobals {
-            symbol_interner: Lock::new(symbol::Interner::fresh()),
+            symbol_interner: symbol::Interner::fresh(),
             span_interner: Lock::new(span_encoding::SpanInterner::default()),
             hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
             source_map: Lock::new(None),
index c816d06045681ddebc9d40cf9417ade9768973da..78846d8ffb26b028536923a2d85528a0865637d4 100644 (file)
@@ -5,6 +5,7 @@
 use rustc_arena::DroplessArena;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
+use rustc_data_structures::sync::Lock;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
         panic_2021,
         panic_abort,
         panic_bounds_check,
+        panic_display,
         panic_fmt,
         panic_handler,
         panic_impl,
         panic_unwind,
         panicking,
         param_attrs,
-        parent_trait,
         partial_cmp,
         partial_ord,
         passes,
         unix,
         unlikely,
         unmarked_api,
-        unnamed_fields,
         unpin,
         unreachable,
         unreachable_code,
         wrapping_sub,
         wreg,
         write_bytes,
+        write_str,
         x87_reg,
         xer,
         xmm_reg,
@@ -1623,14 +1624,15 @@ const fn new(n: u32) -> Self {
 
     /// Maps a string to its interned representation.
     pub fn intern(string: &str) -> Self {
-        with_interner(|interner| interner.intern(string))
+        with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
     }
 
     /// Convert to a `SymbolStr`. This is a slowish operation because it
     /// requires locking the symbol interner.
     pub fn as_str(self) -> SymbolStr {
-        with_interner(|interner| unsafe {
-            SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
+        with_session_globals(|session_globals| {
+            let symbol_str = session_globals.symbol_interner.get(self);
+            unsafe { SymbolStr { string: std::mem::transmute::<&str, &str>(symbol_str) } }
         })
     }
 
@@ -1639,7 +1641,7 @@ pub fn as_u32(self) -> u32 {
     }
 
     pub fn len(self) -> usize {
-        with_interner(|interner| interner.get(self).len())
+        with_session_globals(|session_globals| session_globals.symbol_interner.get(self).len())
     }
 
     pub fn is_empty(self) -> bool {
@@ -1696,13 +1698,19 @@ fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
     }
 }
 
+#[derive(Default)]
+pub(crate) struct Interner(Lock<InternerInner>);
+
 // The `&'static str`s in this type actually point into the arena.
 //
 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
 // found that to regress performance up to 2% in some cases. This might be
 // revisited after further improvements to `indexmap`.
+//
+// This type is private to prevent accidentally constructing more than one `Interner` on the same
+// thread, which makes it easy to mixup `Symbol`s between `Interner`s.
 #[derive(Default)]
-pub struct Interner {
+struct InternerInner {
     arena: DroplessArena,
     names: FxHashMap<&'static str, Symbol>,
     strings: Vec<&'static str>,
@@ -1710,37 +1718,38 @@ pub struct Interner {
 
 impl Interner {
     fn prefill(init: &[&'static str]) -> Self {
-        Interner {
+        Interner(Lock::new(InternerInner {
             strings: init.into(),
             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
             ..Default::default()
-        }
+        }))
     }
 
     #[inline]
-    pub fn intern(&mut self, string: &str) -> Symbol {
-        if let Some(&name) = self.names.get(string) {
+    fn intern(&self, string: &str) -> Symbol {
+        let mut inner = self.0.lock();
+        if let Some(&name) = inner.names.get(string) {
             return name;
         }
 
-        let name = Symbol::new(self.strings.len() as u32);
+        let name = Symbol::new(inner.strings.len() as u32);
 
         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
         // UTF-8.
         let string: &str =
-            unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
+            unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
         // It is safe to extend the arena allocation to `'static` because we only access
         // these while the arena is still alive.
         let string: &'static str = unsafe { &*(string as *const str) };
-        self.strings.push(string);
-        self.names.insert(string, name);
+        inner.strings.push(string);
+        inner.names.insert(string, name);
         name
     }
 
     // Get the symbol as a string. `Symbol::as_str()` should be used in
     // preference to this function.
-    pub fn get(&self, symbol: Symbol) -> &str {
-        self.strings[symbol.0.as_usize()]
+    fn get(&self, symbol: Symbol) -> &str {
+        self.0.lock().strings[symbol.0.as_usize()]
     }
 }
 
@@ -1871,11 +1880,6 @@ pub fn is_raw_guess(self) -> bool {
     }
 }
 
-#[inline]
-fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
-    with_session_globals(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
-}
-
 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
 /// be accessed. It deliberately has limited functionality and should only be
 /// used for temporary values.
index 11dea265b4e66c6adb3769195bf6d234bbf8919f..0958fce5fee304fbd6f918a16efcf40e65e47cef 100644 (file)
@@ -4,7 +4,7 @@
 
 #[test]
 fn interner_tests() {
-    let mut i: Interner = Interner::default();
+    let i = Interner::default();
     // first one is zero:
     assert_eq!(i.intern("dog"), Symbol::new(0));
     // re-use gets the same entry:
index b743c809ca2434926b49c0f80ee205744d366cd5..8abcdb5e89b47b697091b36183f91408adf28419 100644 (file)
@@ -499,7 +499,7 @@ fn generate_member_constraint(
     /// - `substs`, the substs  used to instantiate this opaque type
     /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
     ///   `opaque_defn.concrete_ty`
-    #[instrument(skip(self))]
+    #[instrument(level = "debug", skip(self))]
     fn infer_opaque_definition_from_instantiation(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
@@ -863,7 +863,7 @@ struct Instantiator<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> Instantiator<'a, 'tcx> {
-    #[instrument(skip(self))]
+    #[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 {
index 7a690af0cc6e5e78e49a3dfc645979438e41c6ce..9c962d30ce0e8b8a575627173b019c993dee5b16 100644 (file)
@@ -57,7 +57,6 @@ fn select_all_or_error(
                 .map(|obligation| FulfillmentError {
                     obligation: obligation.clone(),
                     code: FulfillmentErrorCode::CodeAmbiguity,
-                    points_at_arg_span: false,
                     // FIXME - does Chalk have a notation of 'root obligation'?
                     // This is just for diagnostics, so it's okay if this is wrong
                     root_obligation: obligation.clone(),
@@ -112,7 +111,6 @@ fn select_where_possible(
                                     code: FulfillmentErrorCode::CodeSelectionError(
                                         SelectionError::Unimplemented,
                                     ),
-                                    points_at_arg_span: false,
                                     // FIXME - does Chalk have a notation of 'root obligation'?
                                     // This is just for diagnostics, so it's okay if this is wrong
                                     root_obligation: obligation,
@@ -129,7 +127,6 @@ fn select_where_possible(
                         code: FulfillmentErrorCode::CodeSelectionError(
                             SelectionError::Unimplemented,
                         ),
-                        points_at_arg_span: false,
                         // FIXME - does Chalk have a notation of 'root obligation'?
                         // This is just for diagnostics, so it's okay if this is wrong
                         root_obligation: obligation,
index 761b217c78f4e49c8734b8c638ef963c68763ee9..e435154d9318e7b087a7bc98c84097b4f3e51b64 100644 (file)
@@ -66,7 +66,6 @@ fn report_selection_error(
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
         fallback_has_occurred: bool,
-        points_at_arg: bool,
     );
 
     /// Given some node representing a fn-like thing in the HIR map,
@@ -237,7 +236,6 @@ fn report_selection_error(
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
         fallback_has_occurred: bool,
-        points_at_arg: bool,
     ) {
         let tcx = self.tcx;
         let mut span = obligation.cause.span;
@@ -387,7 +385,6 @@ fn report_selection_error(
                             &obligation,
                             &mut err,
                             &trait_ref,
-                            points_at_arg,
                             have_alt_message,
                         ) {
                             self.note_obligation_cause(&mut err, &obligation);
@@ -430,8 +427,8 @@ fn report_selection_error(
                             err.span_label(enclosing_scope_span, s.as_str());
                         }
 
-                        self.suggest_dereferences(&obligation, &mut err, trait_ref, points_at_arg);
-                        self.suggest_fn_call(&obligation, &mut err, trait_ref, points_at_arg);
+                        self.suggest_dereferences(&obligation, &mut err, trait_ref);
+                        self.suggest_fn_call(&obligation, &mut err, trait_ref);
                         self.suggest_remove_reference(&obligation, &mut err, trait_ref);
                         self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
                         self.note_version_mismatch(&mut err, &trait_ref);
@@ -500,12 +497,7 @@ fn report_selection_error(
                         // Changing mutability doesn't make a difference to whether we have
                         // an `Unsize` impl (Fixes ICE in #71036)
                         if !is_unsize {
-                            self.suggest_change_mut(
-                                &obligation,
-                                &mut err,
-                                trait_ref,
-                                points_at_arg,
-                            );
+                            self.suggest_change_mut(&obligation, &mut err, trait_ref);
                         }
 
                         // If this error is due to `!: Trait` not implemented but `(): Trait` is
@@ -730,7 +722,10 @@ fn report_selection_error(
                 };
 
                 let found_did = match *found_trait_ty.kind() {
-                    ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
+                    ty::Closure(did, _)
+                    | ty::Foreign(did)
+                    | ty::FnDef(did, _)
+                    | ty::Generator(did, ..) => Some(did),
                     ty::Adt(def, _) => Some(def.did),
                     _ => None,
                 };
@@ -1214,7 +1209,6 @@ fn report_fulfillment_error(
                     &error.root_obligation,
                     selection_error,
                     fallback_has_occurred,
-                    error.points_at_arg_span,
                 );
             }
             FulfillmentErrorCode::CodeProjectionError(ref e) => {
index 3a32f1cb903e583f24117db65fc84197e2aa3b84..6128c119b6b765568a68dc692cccdfca332c368f 100644 (file)
@@ -154,9 +154,6 @@ fn on_unimplemented_note(
                 flags.push((sym::from_method, Some(method.to_string())));
             }
         }
-        if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) {
-            flags.push((sym::parent_trait, Some(t)));
-        }
 
         if let Some(k) = obligation.cause.span.desugaring_kind() {
             flags.push((sym::from_desugaring, None));
index 9371ff3405eb04aefe6c3eca22c305faffd2349e..ae61988928f78e6ba2f317016718c2cf1df01c3f 100644 (file)
@@ -9,6 +9,7 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_data_structures::sync::Lrc;
 use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -54,7 +55,6 @@ fn suggest_dereferences(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        points_at_arg: bool,
     );
 
     fn get_closure_name(
@@ -69,7 +69,6 @@ fn suggest_fn_call(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
     );
 
     fn suggest_add_reference_to_arg(
@@ -77,7 +76,6 @@ fn suggest_add_reference_to_arg(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
         has_custom_message: bool,
     ) -> bool;
 
@@ -93,7 +91,6 @@ fn suggest_change_mut(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
     );
 
     fn suggest_semicolon_removal(
@@ -490,16 +487,19 @@ fn suggest_dereferences(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        points_at_arg: bool,
     ) {
         // It only make sense when suggesting dereferences for arguments
-        if !points_at_arg {
+        let code = if let ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } =
+            &obligation.cause.code
+        {
+            parent_code.clone()
+        } else {
             return;
-        }
+        };
         let param_env = obligation.param_env;
         let body_id = obligation.cause.body_id;
         let span = obligation.cause.span;
-        let real_trait_ref = match &obligation.cause.code {
+        let real_trait_ref = match &*code {
             ObligationCauseCode::ImplDerivedObligation(cause)
             | ObligationCauseCode::DerivedObligation(cause)
             | ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_ref,
@@ -584,7 +584,6 @@ fn suggest_fn_call(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
     ) {
         let self_ty = match trait_ref.self_ty().no_bound_vars() {
             None => return,
@@ -656,11 +655,11 @@ fn suggest_fn_call(
             }
             _ => return,
         };
-        if points_at_arg {
+        if matches!(obligation.cause.code, ObligationCauseCode::FunctionArgumentObligation { .. }) {
             // When the obligation error has been ensured to have been caused by
             // an argument, the `obligation.cause.span` points at the expression
-            // of the argument, so we can provide a suggestion. This is signaled
-            // by `points_at_arg`. Otherwise, we give a more general note.
+            // of the argument, so we can provide a suggestion. Otherwise, we give
+            // a more general note.
             err.span_suggestion_verbose(
                 obligation.cause.span.shrink_to_hi(),
                 &msg,
@@ -677,18 +676,21 @@ fn suggest_add_reference_to_arg(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
         has_custom_message: bool,
     ) -> bool {
         let span = obligation.cause.span;
-        let points_at_for_iter = matches!(
-            span.ctxt().outer_expn_data().kind,
-            ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
-        );
 
-        if !points_at_arg && !points_at_for_iter {
+        let code = if let ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } =
+            &obligation.cause.code
+        {
+            parent_code.clone()
+        } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter)) =
+            span.ctxt().outer_expn_data().kind
+        {
+            Lrc::new(obligation.cause.code.clone())
+        } else {
             return false;
-        }
+        };
 
         // List of traits for which it would be nonsensical to suggest borrowing.
         // For instance, immutable references are always Copy, so suggesting to
@@ -787,7 +789,7 @@ fn suggest_add_reference_to_arg(
             return false;
         };
 
-        if let ObligationCauseCode::ImplDerivedObligation(obligation) = &obligation.cause.code {
+        if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code {
             let expected_trait_ref = obligation.parent_trait_ref.skip_binder();
             let new_imm_trait_ref =
                 ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs);
@@ -799,7 +801,7 @@ fn suggest_add_reference_to_arg(
                 return try_borrowing(new_mut_trait_ref, expected_trait_ref, true, &[]);
             }
         } else if let ObligationCauseCode::BindingObligation(_, _)
-        | ObligationCauseCode::ItemObligation(_) = &obligation.cause.code
+        | ObligationCauseCode::ItemObligation(_) = &*code
         {
             if try_borrowing(
                 ty::TraitRef::new(trait_ref.def_id, imm_substs),
@@ -891,8 +893,12 @@ fn suggest_change_mut(
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        points_at_arg: bool,
     ) {
+        let points_at_arg = matches!(
+            obligation.cause.code,
+            ObligationCauseCode::FunctionArgumentObligation { .. },
+        );
+
         let span = obligation.cause.span;
         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
             let refs_number =
@@ -1250,33 +1256,40 @@ fn report_closure_arg_mismatch(
             trait_ref: ty::PolyTraitRef<'tcx>,
         ) -> String {
             let inputs = trait_ref.skip_binder().substs.type_at(1);
-            let sig = if let ty::Tuple(inputs) = inputs.kind() {
-                tcx.mk_fn_sig(
-                    inputs.iter().map(|k| k.expect_ty()),
-                    tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
-                    false,
-                    hir::Unsafety::Normal,
-                    abi::Abi::Rust,
-                )
-            } else {
-                tcx.mk_fn_sig(
+            let sig = match inputs.kind() {
+                ty::Tuple(inputs)
+                    if tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
+                {
+                    tcx.mk_fn_sig(
+                        inputs.iter().map(|k| k.expect_ty()),
+                        tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
+                        false,
+                        hir::Unsafety::Normal,
+                        abi::Abi::Rust,
+                    )
+                }
+                _ => tcx.mk_fn_sig(
                     std::iter::once(inputs),
                     tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
                     false,
                     hir::Unsafety::Normal,
                     abi::Abi::Rust,
-                )
+                ),
             };
             trait_ref.rebind(sig).to_string()
         }
 
-        let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
+        let argument_kind = match expected_ref.skip_binder().substs.type_at(0) {
+            t if t.is_closure() => "closure",
+            t if t.is_generator() => "generator",
+            _ => "function",
+        };
         let mut err = struct_span_err!(
             self.tcx.sess,
             span,
             E0631,
             "type mismatch in {} arguments",
-            if argument_is_closure { "closure" } else { "function" }
+            argument_kind
         );
 
         let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
@@ -2289,6 +2302,56 @@ fn note_obligation_cause_code<T>(
                     )
                 });
             }
+            ObligationCauseCode::FunctionArgumentObligation {
+                arg_hir_id,
+                call_hir_id,
+                ref parent_code,
+            } => {
+                let hir = self.tcx.hir();
+                if let Some(Node::Expr(expr @ hir::Expr { kind: hir::ExprKind::Block(..), .. })) =
+                    hir.find(arg_hir_id)
+                {
+                    let in_progress_typeck_results =
+                        self.in_progress_typeck_results.map(|t| t.borrow());
+                    let parent_id = hir.local_def_id(hir.get_parent_item(arg_hir_id));
+                    let typeck_results: &TypeckResults<'tcx> = match &in_progress_typeck_results {
+                        Some(t) if t.hir_owner == parent_id => t,
+                        _ => self.tcx.typeck(parent_id),
+                    };
+                    let ty = typeck_results.expr_ty_adjusted(expr);
+                    let span = expr.peel_blocks().span;
+                    if Some(span) != err.span.primary_span() {
+                        err.span_label(
+                            span,
+                            &if ty.references_error() {
+                                String::new()
+                            } else {
+                                format!("this tail expression is of type `{:?}`", ty)
+                            },
+                        );
+                    }
+                }
+                if let Some(Node::Expr(hir::Expr {
+                    kind:
+                        hir::ExprKind::Call(hir::Expr { span, .. }, _)
+                        | hir::ExprKind::MethodCall(_, span, ..),
+                    ..
+                })) = hir.find(call_hir_id)
+                {
+                    if Some(*span) != err.span.primary_span() {
+                        err.span_label(*span, "required by a bound introduced by this call");
+                    }
+                }
+                ensure_sufficient_stack(|| {
+                    self.note_obligation_cause_code(
+                        err,
+                        predicate,
+                        &parent_code,
+                        obligated_types,
+                        seen_requirements,
+                    )
+                });
+            }
             ObligationCauseCode::CompareImplMethodObligation {
                 item_name,
                 trait_item_def_id,
index 92db0ca2a7c403d6c5f6c2666f6f9f33bd158cdd..4f22543950c0bf5785e00c10383b34c5b4879f3e 100644 (file)
@@ -1477,7 +1477,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
             }
             super::ImplSource::AutoImpl(..)
             | super::ImplSource::Builtin(..)
-            | super::ImplSource::TraitUpcasting(_) => {
+            | super::ImplSource::TraitUpcasting(_)
+            | super::ImplSource::ConstDrop(_) => {
                 // These traits have no associated types.
                 selcx.tcx().sess.delay_span_bug(
                     obligation.cause.span,
@@ -1549,7 +1550,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
         | super::ImplSource::Param(..)
         | super::ImplSource::Builtin(..)
         | super::ImplSource::TraitUpcasting(_)
-        | super::ImplSource::TraitAlias(..) => {
+        | super::ImplSource::TraitAlias(..)
+        | super::ImplSource::ConstDrop(_) => {
             // we don't create Select candidates with this kind of resolution
             span_bug!(
                 obligation.cause.span,
index e18828fec3f6bf6aedaabb5ff8e5f605ae0ee007..6d64dc8254bb4a426379aa977ba7790e6000a16a 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_hir as hir;
 use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, TypeFoldable};
+use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_target::spec::abi::Abi;
 
 use crate::traits::coherence::Conflict;
@@ -277,6 +277,16 @@ pub(super) fn assemble_candidates<'o>(
             self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
         } else if lang_items.unsize_trait() == Some(def_id) {
             self.assemble_candidates_for_unsizing(obligation, &mut candidates);
+        } else if lang_items.drop_trait() == Some(def_id)
+            && obligation.predicate.skip_binder().constness == ty::BoundConstness::ConstIfConst
+        {
+            if self.is_in_const_context {
+                self.assemble_const_drop_candidates(obligation, &mut candidates)?;
+            } else {
+                debug!("passing ~const Drop bound; in non-const context");
+                // `~const Drop` when we are not in a const context has no effect.
+                candidates.vec.push(ConstDropCandidate)
+            }
         } else {
             if lang_items.clone_trait() == Some(def_id) {
                 // Same builtin conditions as `Copy`, i.e., every type which has builtin support
@@ -803,4 +813,118 @@ fn assemble_builtin_bound_candidates(
             }
         }
     }
+
+    fn assemble_const_drop_candidates(
+        &mut self,
+        obligation: &TraitObligation<'tcx>,
+        candidates: &mut SelectionCandidateSet<'tcx>,
+    ) -> Result<(), SelectionError<'tcx>> {
+        let mut stack: Vec<(Ty<'tcx>, usize)> = vec![(obligation.self_ty().skip_binder(), 0)];
+
+        while let Some((ty, depth)) = stack.pop() {
+            let mut noreturn = false;
+
+            self.check_recursion_depth(depth, obligation)?;
+            let mut copy_candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
+            let mut copy_obligation =
+                obligation.with(obligation.predicate.rebind(ty::TraitPredicate {
+                    trait_ref: ty::TraitRef {
+                        def_id: self.tcx().require_lang_item(hir::LangItem::Copy, None),
+                        substs: self.tcx().mk_substs_trait(ty, &[]),
+                    },
+                    constness: ty::BoundConstness::NotConst,
+                }));
+            copy_obligation.recursion_depth = depth + 1;
+            self.assemble_candidates_from_impls(&copy_obligation, &mut copy_candidates);
+            let copy_conditions = self.copy_clone_conditions(&copy_obligation);
+            self.assemble_builtin_bound_candidates(copy_conditions, &mut copy_candidates);
+            if !copy_candidates.vec.is_empty() {
+                noreturn = true;
+            }
+            debug!(?copy_candidates.vec, "assemble_const_drop_candidates - copy");
+
+            match ty.kind() {
+                ty::Int(_)
+                | ty::Uint(_)
+                | ty::Float(_)
+                | ty::Infer(ty::IntVar(_))
+                | ty::Infer(ty::FloatVar(_))
+                | ty::FnPtr(_)
+                | ty::Never
+                | ty::Ref(..)
+                | ty::FnDef(..)
+                | ty::RawPtr(_)
+                | ty::Bool
+                | ty::Char
+                | ty::Str
+                | ty::Foreign(_) => {} // Do nothing. These types satisfy `const Drop`.
+
+                ty::Adt(def, subst) => {
+                    let mut set = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
+                    self.assemble_candidates_from_impls(
+                        &obligation.with(obligation.predicate.map_bound(|mut pred| {
+                            pred.trait_ref.substs = self.tcx().mk_substs_trait(ty, &[]);
+                            pred
+                        })),
+                        &mut set,
+                    );
+                    stack.extend(def.all_fields().map(|f| (f.ty(self.tcx(), subst), depth + 1)));
+
+                    debug!(?set.vec, "assemble_const_drop_candidates - ty::Adt");
+                    if set.vec.into_iter().any(|candidate| {
+                        if let SelectionCandidate::ImplCandidate(did) = candidate {
+                            matches!(self.tcx().impl_constness(did), hir::Constness::NotConst)
+                        } else {
+                            false
+                        }
+                    }) {
+                        if !noreturn {
+                            // has non-const Drop
+                            return Ok(());
+                        }
+                        debug!("not returning");
+                    }
+                }
+
+                ty::Array(ty, _) => stack.push((ty, depth + 1)),
+
+                ty::Tuple(_) => stack.extend(ty.tuple_fields().map(|t| (t, depth + 1))),
+
+                ty::Closure(_, substs) => {
+                    stack.extend(substs.as_closure().upvar_tys().map(|t| (t, depth + 1)))
+                }
+
+                ty::Generator(_, substs, _) => {
+                    let substs = substs.as_generator();
+                    stack.extend(substs.upvar_tys().map(|t| (t, depth + 1)));
+                    stack.push((substs.witness(), depth + 1));
+                }
+
+                ty::GeneratorWitness(tys) => stack.extend(
+                    self.tcx().erase_late_bound_regions(*tys).iter().map(|t| (t, depth + 1)),
+                ),
+
+                ty::Slice(ty) => stack.push((ty, depth + 1)),
+
+                ty::Opaque(..)
+                | ty::Dynamic(..)
+                | ty::Error(_)
+                | ty::Bound(..)
+                | ty::Infer(_)
+                | ty::Placeholder(_)
+                | ty::Projection(..)
+                | ty::Param(..) => {
+                    if !noreturn {
+                        return Ok(());
+                    }
+                    debug!("not returning");
+                }
+            }
+            debug!(?stack, "assemble_const_drop_candidates - in loop");
+        }
+        // all types have passed.
+        candidates.vec.push(ConstDropCandidate);
+
+        Ok(())
+    }
 }
index 6fae8173985be82c233b0ce04dcac77e09b7e55c..3b6555de912e959465d14a13180ee4ed2ffdd9a7 100644 (file)
@@ -28,7 +28,7 @@
 use crate::traits::VtblSegment;
 use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
 use crate::traits::{
-    ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
+    ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceConstDropData,
     ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData,
     ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
     ImplSourceTraitUpcastingData, ImplSourceUserDefinedData,
@@ -124,6 +124,8 @@ pub(super) fn confirm_candidate(
                 let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?;
                 Ok(ImplSource::TraitUpcasting(data))
             }
+
+            ConstDropCandidate => Ok(ImplSource::ConstDrop(ImplSourceConstDropData)),
         }
     }
 
index f5be8bf0949e6ff12caff47d9269a7ca6c2519da..a3a9086c5ad90e549093bd9a73b924c57b6a7f48 100644 (file)
 use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
 use super::wf;
 use super::DerivedObligationCause;
+use super::Normalized;
 use super::Obligation;
 use super::ObligationCauseCode;
 use super::Selection;
 use super::SelectionResult;
 use super::TraitQueryMode;
-use super::{Normalized, ProjectionCacheKey};
 use super::{ObligationCause, PredicateObligation, TraitObligation};
 use super::{Overflow, SelectionError, Unimplemented};
 
 use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::traits::error_reporting::InferCtxtExt;
-use crate::traits::project::ProjectionCacheKeyExt;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lrc;
@@ -574,14 +573,7 @@ fn evaluate_predicate_recursively<'o>(
                     match project::poly_project_and_unify_type(self, &project_obligation) {
                         Ok(Ok(Some(mut subobligations))) => {
                             self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
-                            let result = self
-                                .evaluate_predicates_recursively(previous_stack, subobligations);
-                            if let Some(key) =
-                                ProjectionCacheKey::from_poly_projection_predicate(self, data)
-                            {
-                                self.infcx.inner.borrow_mut().projection_cache().complete(key);
-                            }
-                            result
+                            self.evaluate_predicates_recursively(previous_stack, subobligations)
                         }
                         Ok(Ok(None)) => Ok(EvaluatedToAmbig),
                         Ok(Err(project::InProgress)) => Ok(EvaluatedToRecur),
@@ -1038,19 +1030,15 @@ fn add_depth<T: 'cx, I: Iterator<Item = &'cx mut Obligation<'tcx, T>>>(
         it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1);
     }
 
-    /// Checks that the recursion limit has not been exceeded.
-    ///
-    /// The weird return type of this function allows it to be used with the `try` (`?`)
-    /// operator within certain functions.
-    fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+    fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
         &self,
-        obligation: &Obligation<'tcx, T>,
-        error_obligation: &Obligation<'tcx, V>,
+        depth: usize,
+        error_obligation: &Obligation<'tcx, T>,
     ) -> Result<(), OverflowError> {
-        if !self.infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) {
+        if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
             match self.query_mode {
                 TraitQueryMode::Standard => {
-                    self.infcx().report_overflow_error(error_obligation, true);
+                    self.infcx.report_overflow_error(error_obligation, true);
                 }
                 TraitQueryMode::Canonical => {
                     return Err(OverflowError);
@@ -1060,6 +1048,19 @@ fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFolda
         Ok(())
     }
 
+    /// Checks that the recursion limit has not been exceeded.
+    ///
+    /// The weird return type of this function allows it to be used with the `try` (`?`)
+    /// operator within certain functions.
+    #[inline(always)]
+    fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+        &self,
+        obligation: &Obligation<'tcx, T>,
+        error_obligation: &Obligation<'tcx, V>,
+    ) -> Result<(), OverflowError> {
+        self.check_recursion_depth(obligation.recursion_depth, error_obligation)
+    }
+
     fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
     where
         OP: FnOnce(&mut Self) -> R,
@@ -1079,28 +1080,23 @@ fn filter_impls(
         let tcx = self.tcx();
         // Respect const trait obligations
         if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
-            if Some(obligation.predicate.skip_binder().trait_ref.def_id)
-                != tcx.lang_items().sized_trait()
-            // const Sized bounds are skipped
-            {
-                match candidate {
-                    // const impl
-                    ImplCandidate(def_id)
-                        if tcx.impl_constness(def_id) == hir::Constness::Const => {}
-                    // const param
-                    ParamCandidate(ty::ConstnessAnd {
-                        constness: ty::BoundConstness::ConstIfConst,
-                        ..
-                    }) => {}
-                    // auto trait impl
-                    AutoImplCandidate(..) => {}
-                    // generator, this will raise error in other places
-                    // or ignore error with const_async_blocks feature
-                    GeneratorCandidate => {}
-                    _ => {
-                        // reject all other types of candidates
-                        return Err(Unimplemented);
-                    }
+            match candidate {
+                // const impl
+                ImplCandidate(def_id) if tcx.impl_constness(def_id) == hir::Constness::Const => {}
+                // const param
+                ParamCandidate(ty::ConstnessAnd {
+                    constness: ty::BoundConstness::ConstIfConst,
+                    ..
+                }) => {}
+                // auto trait impl
+                AutoImplCandidate(..) => {}
+                // generator, this will raise error in other places
+                // or ignore error with const_async_blocks feature
+                GeneratorCandidate => {}
+                ConstDropCandidate => {}
+                _ => {
+                    // reject all other types of candidates
+                    return Err(Unimplemented);
                 }
             }
         }
@@ -1476,21 +1472,24 @@ fn candidate_should_be_dropped_in_favor_of(
             (
                 BuiltinCandidate { has_nested: false }
                 | DiscriminantKindCandidate
-                | PointeeCandidate,
+                | PointeeCandidate
+                | ConstDropCandidate,
                 _,
             ) => true,
             (
                 _,
                 BuiltinCandidate { has_nested: false }
                 | DiscriminantKindCandidate
-                | PointeeCandidate,
+                | PointeeCandidate
+                | ConstDropCandidate,
             ) => false,
 
             (ParamCandidate(other), ParamCandidate(victim)) => {
-                let value_same_except_bound_vars = other.value.skip_binder()
+                let same_except_bound_vars = other.value.skip_binder()
                     == victim.value.skip_binder()
+                    && other.constness == victim.constness
                     && !other.value.skip_binder().has_escaping_bound_vars();
-                if value_same_except_bound_vars {
+                if same_except_bound_vars {
                     // See issue #84398. In short, we can generate multiple ParamCandidates which are
                     // the same except for unused bound vars. Just pick the one with the fewest bound vars
                     // or the current one if tied (they should both evaluate to the same answer). This is
index b00d2ab35617f5d8986357ffe9c13d4a9ba545d9..87b729faa54e0ad5f34796d330d236b9270612e7 100644 (file)
@@ -386,7 +386,8 @@ fn resolve_associated_item<'tcx>(
         | traits::ImplSource::TraitAlias(..)
         | traits::ImplSource::DiscriminantKind(..)
         | traits::ImplSource::Pointee(..)
-        | traits::ImplSource::TraitUpcasting(_) => None,
+        | traits::ImplSource::TraitUpcasting(_)
+        | traits::ImplSource::ConstDrop(_) => None,
     })
 }
 
index d837af85d58ae912933b202a95a927b043026b97..32d271d94c8ea2ac79984c2fc5b7562237191e12 100644 (file)
 type NeedsDropResult<T> = Result<T, AlwaysRequiresDrop>;
 
 fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-    let adt_fields =
+    let adt_components =
         move |adt_def: &ty::AdtDef| tcx.adt_drop_tys(adt_def.did).map(|tys| tys.iter());
+
     // If we don't know a type doesn't need drop, for example if it's a type
     // parameter without a `Copy` bound, then we conservatively return that it
     // needs drop.
-    let res = NeedsDropTypes::new(tcx, query.param_env, query.value, adt_fields).next().is_some();
+    let res =
+        NeedsDropTypes::new(tcx, query.param_env, query.value, adt_components).next().is_some();
+
     debug!("needs_drop_raw({:?}) = {:?}", query, res);
     res
 }
index d101551085976077688375471a3592fcfe0567f5..1cc06b8c2e544b9ca5bdf2130cd61ea1dd21b46f 100644 (file)
@@ -72,7 +72,16 @@ pub fn check_call(
         arg_exprs: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        let original_callee_ty = self.check_expr(callee_expr);
+        let original_callee_ty = match &callee_expr.kind {
+            hir::ExprKind::Path(hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)) => self
+                .check_expr_with_expectation_and_args(
+                    callee_expr,
+                    Expectation::NoExpectation,
+                    arg_exprs,
+                ),
+            _ => self.check_expr(callee_expr),
+        };
+
         let expr_ty = self.structurally_resolved_type(call_expr.span, original_callee_ty);
 
         let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
index 6fe96e4cc27b2f0811939203903e8379b1cc5f4c..013aecae586ca93369917a4e7008377de62e4dbb 100644 (file)
@@ -707,13 +707,7 @@ fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceRe
 
                 // Object safety violations or miscellaneous.
                 Err(err) => {
-                    self.report_selection_error(
-                        obligation.clone(),
-                        &obligation,
-                        &err,
-                        false,
-                        false,
-                    );
+                    self.report_selection_error(obligation.clone(), &obligation, &err, false);
                     // Treat this like an obligation and follow through
                     // with the unsizing - the lack of a coercion should
                     // be silent, as it causes a type mismatch later.
index d578fac4cdb227d0ed1ce86dc250d1cb24a18969..917adf0e2b9bfa17b489ed22f99c0b243be9d3e3 100644 (file)
@@ -161,6 +161,17 @@ pub(super) fn check_expr_with_expectation(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
+    ) -> Ty<'tcx> {
+        self.check_expr_with_expectation_and_args(expr, expected, &[])
+    }
+
+    /// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
+    /// `ExprKind::Call` when evaluating its callee when it is an `ExprKind::Path`.
+    pub(super) fn check_expr_with_expectation_and_args(
+        &self,
+        expr: &'tcx hir::Expr<'tcx>,
+        expected: Expectation<'tcx>,
+        args: &'tcx [hir::Expr<'tcx>],
     ) -> Ty<'tcx> {
         if self.tcx().sess.verbose() {
             // make this code only run with -Zverbose because it is probably slow
@@ -198,7 +209,12 @@ pub(super) fn check_expr_with_expectation(
         let old_diverges = self.diverges.replace(Diverges::Maybe);
         let old_has_errors = self.has_errors.replace(false);
 
-        let ty = ensure_sufficient_stack(|| self.check_expr_kind(expr, expected));
+        let ty = ensure_sufficient_stack(|| match &expr.kind {
+            hir::ExprKind::Path(
+                qpath @ hir::QPath::Resolved(..) | qpath @ hir::QPath::TypeRelative(..),
+            ) => self.check_expr_path(qpath, expr, args),
+            _ => self.check_expr_kind(expr, expected),
+        });
 
         // Warn for non-block expressions with diverging children.
         match expr.kind {
@@ -261,7 +277,7 @@ fn check_expr_kind(
             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
                 self.check_lang_item_path(lang_item, expr)
             }
-            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr),
+            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
             ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
             ExprKind::LlvmInlineAsm(asm) => {
                 for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
@@ -481,10 +497,11 @@ fn check_lang_item_path(
         self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1
     }
 
-    fn check_expr_path(
+    pub(crate) fn check_expr_path(
         &self,
         qpath: &'tcx hir::QPath<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
+        args: &'tcx [hir::Expr<'tcx>],
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) =
@@ -517,16 +534,17 @@ fn check_expr_path(
                     // We just want to check sizedness, so instead of introducing
                     // placeholder lifetimes with probing, we just replace higher lifetimes
                     // with fresh vars.
+                    let span = args.get(i).map(|a| a.span).unwrap_or(expr.span);
                     let input = self
                         .replace_bound_vars_with_fresh_vars(
-                            expr.span,
+                            span,
                             infer::LateBoundRegionConversionTime::FnCall,
                             fn_sig.input(i),
                         )
                         .0;
                     self.require_type_is_sized_deferred(
                         input,
-                        expr.span,
+                        span,
                         traits::SizedArgumentType(None),
                     );
                 }
@@ -1842,7 +1860,28 @@ fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field
             expr_t
         );
         err.span_label(field.span, "method, not a field");
-        if !self.expr_in_place(expr.hir_id) {
+        let expr_is_call =
+            if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) =
+                self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id))
+            {
+                expr.hir_id == callee.hir_id
+            } else {
+                false
+            };
+        let expr_snippet =
+            self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new());
+        if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") {
+            let after_open = expr.span.lo() + rustc_span::BytePos(1);
+            let before_close = expr.span.hi() - rustc_span::BytePos(1);
+            err.multipart_suggestion(
+                "remove wrapping parentheses to call the method",
+                vec![
+                    (expr.span.with_hi(after_open), String::new()),
+                    (expr.span.with_lo(before_close), String::new()),
+                ],
+                Applicability::MachineApplicable,
+            );
+        } else if !self.expr_in_place(expr.hir_id) {
             self.suggest_method_call(
                 &mut err,
                 "use parentheses to call the method",
index 9748c0835bf12e29c4e6463208899f8f4cfe2fd9..ed01dae59f6723e1460d2a534c8c34faac305813 100644 (file)
@@ -83,7 +83,15 @@ pub(in super::super) fn warn_if_unreachable(&self, id: hir::HirId, span: Span, k
     /// version (resolve_vars_if_possible), this version will
     /// also select obligations if it seems useful, in an effort
     /// to get more type information.
-    pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub(in super::super) fn resolve_vars_with_obligations(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        self.resolve_vars_with_obligations_and_mutate_fulfillment(ty, |_| {})
+    }
+
+    pub(in super::super) fn resolve_vars_with_obligations_and_mutate_fulfillment(
+        &self,
+        mut ty: Ty<'tcx>,
+        mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
+    ) -> Ty<'tcx> {
         debug!("resolve_vars_with_obligations(ty={:?})", ty);
 
         // No Infer()? Nothing needs doing.
@@ -103,7 +111,7 @@ pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -
         // possible. This can help substantially when there are
         // indirect dependencies that don't seem worth tracking
         // precisely.
-        self.select_obligations_where_possible(false, |_| {});
+        self.select_obligations_where_possible(false, mutate_fulfillment_errors);
         ty = self.resolve_vars_if_possible(ty);
 
         debug!("resolve_vars_with_obligations: ty={:?}", ty);
index 9efb52a08b7e10eb98daaab1dd43f2bebf7b5987..551522334aa00a7d9d328bdeb7a361c0f0e36854 100644 (file)
@@ -9,6 +9,7 @@
 };
 
 use rustc_ast as ast;
+use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -324,6 +325,7 @@ pub(in super::super) fn check_argument_types(
                     self.point_at_arg_instead_of_call_if_possible(
                         errors,
                         &final_arg_types[..],
+                        expr,
                         sp,
                         &args,
                     );
@@ -354,8 +356,8 @@ pub(in super::super) fn check_argument_types(
                     continue;
                 }
 
-                debug!("checking the argument");
                 let formal_ty = formal_tys[i];
+                debug!("checking argument {}: {:?} = {:?}", i, arg, formal_ty);
 
                 // The special-cased logic below has three functions:
                 // 1. Provide as good of an expected type as possible.
@@ -367,6 +369,42 @@ pub(in super::super) fn check_argument_types(
                 //    to, which is `expected_ty` if `rvalue_hint` returns an
                 //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
                 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
+
+                // Cause selection errors caused by resolving a single argument to point at the
+                // argument and not the call. This is otherwise redundant with the `demand_coerce`
+                // call immediately after, but it lets us customize the span pointed to in the
+                // fulfillment error to be more accurate.
+                let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment(
+                    coerce_ty,
+                    |errors| {
+                        // This is not coming from a macro or a `derive`.
+                        if sp.desugaring_kind().is_none()
+                        && !arg.span.from_expansion()
+                        // Do not change the spans of `async fn`s.
+                        && !matches!(
+                            expr.kind,
+                            hir::ExprKind::Call(
+                                hir::Expr {
+                                    kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)),
+                                    ..
+                                },
+                                _
+                            )
+                        ) {
+                            for error in errors {
+                                error.obligation.cause.make_mut().span = arg.span;
+                                let code = error.obligation.cause.code.clone();
+                                error.obligation.cause.make_mut().code =
+                                    ObligationCauseCode::FunctionArgumentObligation {
+                                        arg_hir_id: arg.hir_id,
+                                        call_hir_id: expr.hir_id,
+                                        parent_code: Lrc::new(code),
+                                    };
+                            }
+                        }
+                    },
+                );
+
                 // We're processing function arguments so we definitely want to use
                 // two-phase borrows.
                 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
@@ -494,15 +532,25 @@ pub fn check_struct_path(
 
             Some((variant, ty))
         } else {
-            struct_span_err!(
-                self.tcx.sess,
-                path_span,
-                E0071,
-                "expected struct, variant or union type, found {}",
-                ty.sort_string(self.tcx)
-            )
-            .span_label(path_span, "not a struct")
-            .emit();
+            match ty.kind() {
+                ty::Error(_) => {
+                    // E0071 might be caused by a spelling error, which will have
+                    // already caused an error message and probably a suggestion
+                    // elsewhere. Refrain from emitting more unhelpful errors here
+                    // (issue #88844).
+                }
+                _ => {
+                    struct_span_err!(
+                        self.tcx.sess,
+                        path_span,
+                        E0071,
+                        "expected struct, variant or union type, found {}",
+                        ty.sort_string(self.tcx)
+                    )
+                    .span_label(path_span, "not a struct")
+                    .emit();
+                }
+            }
             None
         }
     }
@@ -907,6 +955,7 @@ fn point_at_arg_instead_of_call_if_possible(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
         final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
+        expr: &'tcx hir::Expr<'tcx>,
         call_sp: Span,
         args: &'tcx [hir::Expr<'tcx>],
     ) {
@@ -956,7 +1005,13 @@ fn point_at_arg_instead_of_call_if_possible(
                     // We make sure that only *one* argument matches the obligation failure
                     // and we assign the obligation's span to its expression's.
                     error.obligation.cause.make_mut().span = args[ref_in].span;
-                    error.points_at_arg_span = true;
+                    let code = error.obligation.cause.code.clone();
+                    error.obligation.cause.make_mut().code =
+                        ObligationCauseCode::FunctionArgumentObligation {
+                            arg_hir_id: args[ref_in].hir_id,
+                            call_hir_id: expr.hir_id,
+                            parent_code: Lrc::new(code),
+                        };
                 }
             }
         }
index 140a9d1126d32a29289207c7f7df4bc3884943c8..a056ab6aef2aec0398476a4b793e0cea99b40c19 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::ty::subst::GenericArg;
 use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeFoldable};
+use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::{Span, Spanned};
@@ -1261,7 +1262,8 @@ fn check_struct_pat_fields(
         };
 
         // Require `..` if struct has non_exhaustive attribute.
-        if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
+        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
+        if non_exhaustive && !etc {
             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
 
@@ -1276,7 +1278,7 @@ fn check_struct_pat_fields(
             if etc {
                 tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
             }
-        } else if !etc && !unmentioned_fields.is_empty() {
+        } else if !unmentioned_fields.is_empty() {
             let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
                 .iter()
                 .copied()
@@ -1284,16 +1286,19 @@ fn check_struct_pat_fields(
                     field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
                 })
                 .collect();
-
-            if accessible_unmentioned_fields.is_empty() {
-                unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
-            } else {
-                unmentioned_err = Some(self.error_unmentioned_fields(
-                    pat,
-                    &accessible_unmentioned_fields,
-                    accessible_unmentioned_fields.len() != unmentioned_fields.len(),
-                    &fields,
-                ));
+            if non_exhaustive {
+                self.non_exhaustive_reachable_pattern(pat, &accessible_unmentioned_fields, adt_ty)
+            } else if !etc {
+                if accessible_unmentioned_fields.is_empty() {
+                    unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
+                } else {
+                    unmentioned_err = Some(self.error_unmentioned_fields(
+                        pat,
+                        &accessible_unmentioned_fields,
+                        accessible_unmentioned_fields.len() != unmentioned_fields.len(),
+                        &fields,
+                    ));
+                }
             }
         }
         match (inexistent_fields_err, unmentioned_err) {
@@ -1604,6 +1609,51 @@ fn error_no_accessible_fields(
         err
     }
 
+    /// Report that a pattern for a `#[non_exhaustive]` struct marked with `non_exhaustive_omitted_patterns`
+    /// is not exhaustive enough.
+    ///
+    /// Nb: the partner lint for enums lives in `compiler/rustc_mir_build/src/thir/pattern/usefulness.rs`.
+    fn non_exhaustive_reachable_pattern(
+        &self,
+        pat: &Pat<'_>,
+        unmentioned_fields: &[(&ty::FieldDef, Ident)],
+        ty: Ty<'tcx>,
+    ) {
+        fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String {
+            const LIMIT: usize = 3;
+            match witnesses {
+                [] => bug!(),
+                [witness] => format!("`{}`", witness),
+                [head @ .., tail] if head.len() < LIMIT => {
+                    let head: Vec<_> = head.iter().map(<_>::to_string).collect();
+                    format!("`{}` and `{}`", head.join("`, `"), tail)
+                }
+                _ => {
+                    let (head, tail) = witnesses.split_at(LIMIT);
+                    let head: Vec<_> = head.iter().map(<_>::to_string).collect();
+                    format!("`{}` and {} more", head.join("`, `"), tail.len())
+                }
+            }
+        }
+        let joined_patterns = joined_uncovered_patterns(
+            &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
+        );
+
+        self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |build| {
+        let mut lint = build.build("some fields are not explicitly listed");
+        lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
+
+        lint.help(
+            "ensure that all fields are mentioned explicitly by adding the suggested fields",
+        );
+        lint.note(&format!(
+            "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
+            ty,
+        ));
+        lint.emit();
+    });
+    }
+
     /// Returns a diagnostic reporting a struct pattern which does not mention some fields.
     ///
     /// ```text
index bccc19774e0d94048c6dcaa71d24b989d8103065..7e69ad21d034326a9c1fac72b80946e96a0c6fe8 100644 (file)
@@ -136,10 +136,7 @@ fn num_provided_lifetime_args(&self) -> usize {
             AngleBrackets::Missing => 0,
             // Only lifetime arguments can be implied
             AngleBrackets::Implied => self.gen_args.args.len(),
-            AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
-                hir::GenericArg::Lifetime(_) => acc + 1,
-                _ => acc,
-            }),
+            AngleBrackets::Available => self.gen_args.num_lifetime_params(),
         }
     }
 
@@ -148,10 +145,7 @@ fn num_provided_type_or_const_args(&self) -> usize {
             AngleBrackets::Missing => 0,
             // Only lifetime arguments can be implied
             AngleBrackets::Implied => 0,
-            AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
-                hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => acc + 1,
-                _ => acc,
-            }),
+            AngleBrackets::Available => self.gen_args.num_generic_params(),
         }
     }
 
@@ -651,7 +645,9 @@ fn suggest_removing_args_or_generics(&self, err: &mut DiagnosticBuilder<'_>) {
             let mut found_redundant = false;
             for arg in self.gen_args.args {
                 match arg {
-                    hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => {
+                    hir::GenericArg::Type(_)
+                    | hir::GenericArg::Const(_)
+                    | hir::GenericArg::Infer(_) => {
                         gen_arg_spans.push(arg.span());
                         if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
                             found_redundant = true;
index 482a497201de6d54fba41e8ce4876110ce80df0c..9ecbf0582319e845febdf4cca95e4d822c0bd7c6 100644 (file)
@@ -330,7 +330,11 @@ pub fn into_owned(self) -> <B as ToOwned>::Owned {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B: ?Sized + ToOwned> Deref for Cow<'_, B> {
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
+where
+    B::Owned: ~const Borrow<B>,
+{
     type Target = B;
 
     fn deref(&self) -> &B {
index 4f925f8d81dfa57067537217e501e1dff7433491..cc89bb66f91b2b4a640b0b525ca5d753e3346d7e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4f925f8d81dfa57067537217e501e1dff7433491
+Subproject commit cc89bb66f91b2b4a640b0b525ca5d753e3346d7e
index 2adf6a549e6417b94349752487b39f76257fa727..e56b631dbaf8db537afb2bd8196e709ba074f396 100644 (file)
@@ -1916,7 +1916,8 @@ pub const fn get(&self) -> *mut T {
     /// ```
     #[inline(always)]
     #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")]
-    pub fn get_mut(&mut self) -> &mut T {
+    #[rustc_const_unstable(feature = "const_unsafecell_get_mut", issue = "88836")]
+    pub const fn get_mut(&mut self) -> &mut T {
         &mut self.value
     }
 
index 330d3714247c5024d03c8ce9738dac403d282f0f..b0a9d9f5ef5c9c6f192bf097cae32984d267e3bc 100644 (file)
@@ -2172,8 +2172,9 @@ fn fold<B, F>(mut self, init: B, mut f: F) -> B
     /// If the iterator is empty, returns [`None`]; otherwise, returns the
     /// result of the reduction.
     ///
+    /// The reducing function is a closure with two arguments: an 'accumulator', and an element.
     /// For iterators with at least one element, this is the same as [`fold()`]
-    /// with the first element of the iterator as the initial value, folding
+    /// with the first element of the iterator as the initial accumulator value, folding
     /// every subsequent element into it.
     ///
     /// [`fold()`]: Iterator::fold
@@ -2187,8 +2188,8 @@ fn fold<B, F>(mut self, init: B, mut f: F) -> B
     ///     where I: Iterator,
     ///           I::Item: Ord,
     /// {
-    ///     iter.reduce(|a, b| {
-    ///         if a >= b { a } else { b }
+    ///     iter.reduce(|accum, item| {
+    ///         if accum >= item { accum } else { item }
     ///     })
     /// }
     /// let a = [10, 20, 5, -23, 0];
index d86939454be5b0c4432dec7fe6c97a90da0c5e48..20b6453990d7519ce7199d49733b59fa0c899dd4 100644 (file)
@@ -145,7 +145,8 @@ pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
 }
 
 #[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: ?Sized> Deref for ManuallyDrop<T> {
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const Deref for ManuallyDrop<T> {
     type Target = T;
     #[inline(always)]
     fn deref(&self) -> &T {
@@ -154,7 +155,8 @@ fn deref(&self) -> &T {
 }
 
 #[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const DerefMut for ManuallyDrop<T> {
     #[inline(always)]
     fn deref_mut(&mut self) -> &mut T {
         &mut self.value
index be6d70320d407669839cae46e732bc1471becfa3..b078cdf5479d7ba536cfdefff4584cc369f4e44d 100644 (file)
 ///
 /// assert_eq!(u32::MAX, (zero - one).0);
 /// ```
+///
+/// # Layout
+///
+/// `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
 #[repr(transparent)]
index dcf3ce070ec6578f8b0a220ba78dae0755e1d3f1..fb4ec83bc287e7d42a4ccbf132365d8f910f3951 100644 (file)
@@ -76,7 +76,8 @@ pub trait Deref {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Deref for &T {
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const Deref for &T {
     type Target = T;
 
     #[rustc_diagnostic_item = "noop_method_deref"]
@@ -89,7 +90,8 @@ fn deref(&self) -> &T {
 impl<T: ?Sized> !DerefMut for &T {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Deref for &mut T {
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const Deref for &mut T {
     type Target = T;
 
     fn deref(&self) -> &T {
index 463bec37265d5035c7cbd34bb46d3cd3bc174070..7a8b04d6f3c13c4599201e5c1b6064d854604041 100644 (file)
     ($msg:literal $(,)?) => (
         $crate::panicking::panic($msg)
     ),
+    // Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
     ($msg:expr $(,)?) => (
         $crate::panicking::panic_str($msg)
     ),
+    // Special-case the single-argument case for const_panic.
+    ("{}", $arg:expr $(,)?) => (
+        $crate::panicking::panic_display(&$arg)
+    ),
     ($fmt:expr, $($arg:tt)+) => (
         $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
     ),
     () => (
         $crate::panicking::panic("explicit panic")
     ),
+    // Special-case the single-argument case for const_panic.
+    ("{}", $arg:expr $(,)?) => (
+        $crate::panicking::panic_display(&$arg)
+    ),
     ($($t:tt)+) => (
         $crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
     ),
index 02f32675247c3dba2addb111f9ceed4d73358b12..a6aa4bf43c865292e1764a6a6fa3a02826db2ae3 100644 (file)
@@ -60,6 +60,13 @@ pub fn panic_str(expr: &str) -> ! {
     panic_fmt(format_args!("{}", expr));
 }
 
+#[inline]
+#[track_caller]
+#[cfg_attr(not(bootstrap), lang = "panic_display")] // needed for const-evaluated panics
+pub fn panic_display<T: fmt::Display>(x: &T) -> ! {
+    panic_fmt(format_args!("{}", *x));
+}
+
 #[cold]
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 #[track_caller]
index de05c377852950120a0d70655d2ab94c87a53248..3b9175503080c1e330b2b65a2d67ba420b101a19 100644 (file)
@@ -915,6 +915,7 @@ fn from(s: CString) -> Box<CStr> {
 
 #[stable(feature = "cow_from_cstr", since = "1.28.0")]
 impl<'a> From<CString> for Cow<'a, CStr> {
+    /// Converts a [`CString`] into an owned [`Cow`] without copying or allocating.
     #[inline]
     fn from(s: CString) -> Cow<'a, CStr> {
         Cow::Owned(s)
@@ -923,6 +924,7 @@ fn from(s: CString) -> Cow<'a, CStr> {
 
 #[stable(feature = "cow_from_cstr", since = "1.28.0")]
 impl<'a> From<&'a CStr> for Cow<'a, CStr> {
+    /// Converts a [`CStr`] into a borrowed [`Cow`] without copying or allocating.
     #[inline]
     fn from(s: &'a CStr) -> Cow<'a, CStr> {
         Cow::Borrowed(s)
@@ -931,6 +933,7 @@ fn from(s: &'a CStr) -> Cow<'a, CStr> {
 
 #[stable(feature = "cow_from_cstr", since = "1.28.0")]
 impl<'a> From<&'a CString> for Cow<'a, CStr> {
+    /// Converts a `&`[`CString`] into a borrowed [`Cow`] without copying or allocating.
     #[inline]
     fn from(s: &'a CString) -> Cow<'a, CStr> {
         Cow::Borrowed(s.as_c_str())
index 3af941f59b68918d1417e444428112cdc662e17a..2e93807037464af71fddb3fe7c9004b5b2fcca23 100644 (file)
@@ -77,7 +77,7 @@ mod as_keyword {}
 ///     '_inner: for j in 1..=200 {
 ///         println!("    inner iteration (j): {}", j);
 ///         if j >= 3 {
-///             // breaks from inner loop, let's outer loop continue.
+///             // breaks from inner loop, lets outer loop continue.
 ///             break;
 ///         }
 ///         if i >= 2 {
index 83c6ba0e6ea450e83f76ddfdb58ff26d4063fcda..559d2672a0da38ce72fb2fa658df4c69fdd1910d 100644 (file)
 #![feature(const_trait_impl)]
 #![feature(container_error_extra)]
 #![feature(core_intrinsics)]
+#![feature(core_panic)]
 #![feature(custom_test_frameworks)]
 #![feature(decl_macro)]
 #![feature(doc_cfg)]
index 5b4a9fa7979de644cb0cc043114071cc53dfb480..223726d45d72a4ffe7ee2ad5897c7e97575cbbda 100644 (file)
@@ -96,6 +96,18 @@ pub struct Incoming<'a> {
     listener: &'a TcpListener,
 }
 
+/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
+///
+/// This `struct` is created by the [`TcpListener::into_incoming`] method.
+/// See its documentation for more.
+///
+/// [`accept`]: TcpListener::accept
+#[derive(Debug)]
+#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+pub struct IntoIncoming {
+    listener: TcpListener,
+}
+
 impl TcpStream {
     /// Opens a TCP connection to a remote host.
     ///
@@ -845,6 +857,37 @@ pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 
+    /// Turn this into an iterator over the connections being received on this
+    /// listener.
+    ///
+    /// The returned iterator will never return [`None`] and will also not yield
+    /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
+    /// calling [`TcpListener::accept`] in a loop.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(tcplistener_into_incoming)]
+    /// use std::net::{TcpListener, TcpStream};
+    ///
+    /// fn listen_on(port: u16) -> impl Iterator<Item = TcpStream> {
+    ///     let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+    ///     listener.into_incoming()
+    ///         .filter_map(Result::ok) /* Ignore failed connections */
+    /// }
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     for stream in listen_on(80) {
+    ///         /* handle the connection here */
+    ///     }
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+    pub fn into_incoming(self) -> IntoIncoming {
+        IntoIncoming { listener: self }
+    }
+
     /// Sets the value for the `IP_TTL` option on this socket.
     ///
     /// This value sets the time-to-live field that is used in every packet sent
@@ -982,6 +1025,14 @@ fn next(&mut self) -> Option<io::Result<TcpStream>> {
     }
 }
 
+#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+impl Iterator for IntoIncoming {
+    type Item = io::Result<TcpStream>;
+    fn next(&mut self) -> Option<io::Result<TcpStream>> {
+        Some(self.listener.accept().map(|p| p.0))
+    }
+}
+
 impl AsInner<net_imp::TcpListener> for TcpListener {
     fn as_inner(&self) -> &net_imp::TcpListener {
         &self.0
index 79e6967300767e463a5b6c06f5b2b663c9742809..069a5376a441c9062b8e945ba0f7610b46ddcbc4 100644 (file)
 // of a macro that is not vendored by Rust and included in the toolchain.
 // See https://github.com/rust-analyzer/rust-analyzer/issues/6038.
 
+// On certain platforms right now the "main modules" modules that are
+// documented don't compile (missing things in `libc` which is empty),
+// so just omit them with an empty module and add the "unstable" attribute.
+
+// Unix, linux, wasi and windows are handled a bit differently.
 #[cfg(all(
     doc,
-    not(any(
+    any(
         all(target_arch = "wasm32", not(target_os = "wasi")),
         all(target_vendor = "fortanix", target_env = "sgx")
-    ))
+    )
 ))]
-#[path = "."]
-mod doc {
-    // When documenting std we want to show the `unix`, `windows`, `linux` and `wasi`
-    // modules as these are the "main modules" that are used across platforms,
-    // so these modules are enabled when `cfg(doc)` is set.
-    // This should help show platform-specific functionality in a hopefully cross-platform
-    // way in the documentation.
-
-    pub mod unix;
-
-    pub mod linux;
-
-    pub mod wasi;
-
-    pub mod windows;
-}
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod unix {}
 #[cfg(all(
     doc,
     any(
@@ -40,87 +31,115 @@ mod doc {
         all(target_vendor = "fortanix", target_env = "sgx")
     )
 ))]
-mod doc {
-    // On certain platforms right now the "main modules" modules that are
-    // documented don't compile (missing things in `libc` which is empty),
-    // so just omit them with an empty module.
-
-    #[unstable(issue = "none", feature = "std_internals")]
-    pub mod unix {}
-
-    #[unstable(issue = "none", feature = "std_internals")]
-    pub mod linux {}
-
-    #[unstable(issue = "none", feature = "std_internals")]
-    pub mod wasi {}
-
-    #[unstable(issue = "none", feature = "std_internals")]
-    pub mod windows {}
-}
-#[cfg(doc)]
-#[stable(feature = "os", since = "1.0.0")]
-pub use doc::*;
-
-#[cfg(not(doc))]
-#[path = "."]
-mod imp {
-    // If we're not documenting std then we only expose modules appropriate for the
-    // current platform.
-
-    #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
-    pub mod fortanix_sgx;
-
-    #[cfg(target_os = "hermit")]
-    #[path = "hermit/mod.rs"]
-    pub mod unix;
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod linux {}
+#[cfg(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+))]
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod wasi {}
+#[cfg(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+))]
+#[unstable(issue = "none", feature = "std_internals")]
+pub mod windows {}
 
-    #[cfg(target_os = "android")]
-    pub mod android;
-    #[cfg(target_os = "dragonfly")]
-    pub mod dragonfly;
-    #[cfg(target_os = "emscripten")]
-    pub mod emscripten;
-    #[cfg(target_os = "espidf")]
-    pub mod espidf;
-    #[cfg(target_os = "freebsd")]
-    pub mod freebsd;
-    #[cfg(target_os = "fuchsia")]
-    pub mod fuchsia;
-    #[cfg(target_os = "haiku")]
-    pub mod haiku;
-    #[cfg(target_os = "illumos")]
-    pub mod illumos;
-    #[cfg(target_os = "ios")]
-    pub mod ios;
-    #[cfg(target_os = "l4re")]
-    pub mod linux;
-    #[cfg(target_os = "linux")]
-    pub mod linux;
-    #[cfg(target_os = "macos")]
-    pub mod macos;
-    #[cfg(target_os = "netbsd")]
-    pub mod netbsd;
-    #[cfg(target_os = "openbsd")]
-    pub mod openbsd;
-    #[cfg(target_os = "redox")]
-    pub mod redox;
-    #[cfg(target_os = "solaris")]
-    pub mod solaris;
-    #[cfg(unix)]
-    pub mod unix;
+// unix
+#[cfg(not(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+)))]
+#[cfg(target_os = "hermit")]
+#[path = "hermit/mod.rs"]
+pub mod unix;
+#[cfg(not(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+)))]
+#[cfg(all(not(target_os = "hermit"), any(unix, doc)))]
+pub mod unix;
 
-    #[cfg(target_os = "vxworks")]
-    pub mod vxworks;
+// linux
+#[cfg(not(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+)))]
+#[cfg(any(target_os = "linux", target_os = "l4re", doc))]
+pub mod linux;
 
-    #[cfg(target_os = "wasi")]
-    pub mod wasi;
+// wasi
+#[cfg(not(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+)))]
+#[cfg(any(target_os = "wasi", doc))]
+pub mod wasi;
 
-    #[cfg(windows)]
-    pub mod windows;
-}
-#[cfg(not(doc))]
-#[stable(feature = "os", since = "1.0.0")]
-pub use imp::*;
+// windows
+#[cfg(not(all(
+    doc,
+    any(
+        all(target_arch = "wasm32", not(target_os = "wasi")),
+        all(target_vendor = "fortanix", target_env = "sgx")
+    )
+)))]
+#[cfg(any(windows, doc))]
+pub mod windows;
+
+// Others.
+#[cfg(target_os = "android")]
+pub mod android;
+#[cfg(target_os = "dragonfly")]
+pub mod dragonfly;
+#[cfg(target_os = "emscripten")]
+pub mod emscripten;
+#[cfg(target_os = "espidf")]
+pub mod espidf;
+#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
+pub mod fortanix_sgx;
+#[cfg(target_os = "freebsd")]
+pub mod freebsd;
+#[cfg(target_os = "fuchsia")]
+pub mod fuchsia;
+#[cfg(target_os = "haiku")]
+pub mod haiku;
+#[cfg(target_os = "illumos")]
+pub mod illumos;
+#[cfg(target_os = "ios")]
+pub mod ios;
+#[cfg(target_os = "macos")]
+pub mod macos;
+#[cfg(target_os = "netbsd")]
+pub mod netbsd;
+#[cfg(target_os = "openbsd")]
+pub mod openbsd;
+#[cfg(target_os = "redox")]
+pub mod redox;
+#[cfg(target_os = "solaris")]
+pub mod solaris;
+
+#[cfg(target_os = "vxworks")]
+pub mod vxworks;
 
 #[cfg(any(unix, target_os = "wasi", doc))]
 mod fd;
index 6cf37f23c574d745d2c5fccb30f9dbd53a4f0e8f..30eead9b05901db9db936a01dacb370080669b55 100644 (file)
@@ -5,6 +5,7 @@
 use super::platform::fs::MetadataExt as _;
 use crate::fs::{self, OpenOptions, Permissions};
 use crate::io;
+use crate::os::unix::io::{AsFd, AsRawFd};
 use crate::path::Path;
 use crate::sys;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
@@ -924,6 +925,75 @@ fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
     }
 }
 
+/// Change the owner and group of the specified path.
+///
+/// Specifying either the uid or gid as `None` will leave it unchanged.
+///
+/// Changing the owner typically requires privileges, such as root or a specific capability.
+/// Changing the group typically requires either being the owner and a member of the group, or
+/// having privileges.
+///
+/// If called on a symbolic link, this will change the owner and group of the link target. To
+/// change the owner and group of the link itself, see [`lchown`].
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+///     fs::chown("/sandbox", Some(0), Some(0))?;
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "unix_chown", issue = "88989")]
+pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+    sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
+/// Change the owner and group of the file referenced by the specified open file descriptor.
+///
+/// For semantics and required privileges, see [`chown`].
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+///     let f = std::fs::File::open("/file")?;
+///     fs::fchown(f, Some(0), Some(0))?;
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "unix_chown", issue = "88989")]
+pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+    sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
+/// Change the owner and group of the specified path, without dereferencing symbolic links.
+///
+/// Identical to [`chown`], except that if called on a symbolic link, this will change the owner
+/// and group of the link itself rather than the owner and group of the link target.
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+///     fs::lchown("/symlink", Some(0), Some(0))?;
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "unix_chown", issue = "88989")]
+pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+    sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
 /// Change the root directory of the current process to the specified path.
 ///
 /// This typically requires privileges, such as root or a specific capability.
index c1c039584979d3817f876da3929daf69d1fb0433..21e9669c11079718073c402f8d4135859e7ec7f2 100644 (file)
@@ -10,7 +10,7 @@
 
 #[doc(hidden)]
 #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
-#[allow_internal_unstable(libstd_sys_internals, const_format_args)]
+#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro panic_2015 {
     ($msg:expr $(,)?) => ({
         $crate::rt::begin_panic($msg)
     }),
+    // Special-case the single-argument case for const_panic.
+    ("{}", $arg:expr $(,)?) => ({
+        $crate::rt::panic_display(&$arg)
+    }),
     ($fmt:expr, $($arg:tt)+) => ({
         $crate::rt::begin_panic_fmt(&$crate::const_format_args!($fmt, $($arg)+))
     }),
index 72e6c23ee49907a5b1b760577518ead2d7680ffb..893167e373015ca84c7a7ec242be6c85878991aa 100644 (file)
@@ -16,6 +16,7 @@
 
 // Re-export some of our utilities which are expected by other crates.
 pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count};
+pub use core::panicking::panic_display;
 
 // To reduce the generated code of the new `lang_start`, this function is doing
 // the real work.
@@ -59,10 +60,10 @@ fn lang_start<T: crate::process::Termination + 'static>(
     argc: isize,
     argv: *const *const u8,
 ) -> isize {
-    lang_start_internal(
+    let Ok(v) = lang_start_internal(
         &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
         argc,
         argv,
-    )
-    .into_ok()
+    );
+    v
 }
index 6d7524a733afd85cac14a01793ee06047328f5fc..a4fff9b2e64731c7f775fcff82075bbf3b2c3784 100644 (file)
@@ -1416,6 +1416,23 @@ fn fclonefileat(
     Ok(bytes_copied as u64)
 }
 
+pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
+    let path = cstr(path)?;
+    cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
+    Ok(())
+}
+
+pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> {
+    cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?;
+    Ok(())
+}
+
+pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
+    let path = cstr(path)?;
+    cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })?;
+    Ok(())
+}
+
 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
 pub fn chroot(dir: &Path) -> io::Result<()> {
     let dir = cstr(dir)?;
index fbc7f19cb731cfe309fc419250b51aa1919032e3..af3774b7c7586ef3f33d38747405153b0eb4dff0 100644 (file)
@@ -537,7 +537,7 @@ impl Step for Rustc {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.krate("rustc-main").default_condition(builder.config.docs)
+        run.krate("rustc-main").path("compiler").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -553,9 +553,24 @@ fn make_run(run: RunConfig<'_>) {
     fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
+        let mut is_explicit_request = false;
         builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
 
-        if !builder.config.compiler_docs {
+        let paths = builder
+            .paths
+            .iter()
+            .map(components_simplified)
+            .filter_map(|path| {
+                if path.get(0) == Some(&"compiler") {
+                    is_explicit_request = true;
+                    path.get(1).map(|p| p.to_owned())
+                } else {
+                    None
+                }
+            })
+            .collect::<Vec<_>>();
+
+        if !builder.config.compiler_docs && !is_explicit_request {
             builder.info("\tskipping - compiler/librustdoc docs disabled");
             return;
         }
@@ -589,6 +604,7 @@ fn run(self, builder: &Builder<'_>) {
         cargo.rustdocflag("-Zunstable-options");
         cargo.rustdocflag("-Znormalize-docs");
         cargo.rustdocflag("--show-type-layout");
+        cargo.rustdocflag("--generate-link-to-definition");
         compile::rustc_cargo(builder, &mut cargo, target);
         cargo.arg("-Zunstable-options");
         cargo.arg("-Zskip-rustdoc-fingerprint");
@@ -603,26 +619,54 @@ fn run(self, builder: &Builder<'_>) {
         cargo.rustdocflag("--extern-html-root-url");
         cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
 
-        // Find dependencies for top level crates.
         let mut compiler_crates = HashSet::new();
-        for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
-            compiler_crates.extend(
-                builder
-                    .in_tree_crates(root_crate, Some(target))
-                    .into_iter()
-                    .map(|krate| krate.name),
-            );
+
+        if paths.is_empty() {
+            // Find dependencies for top level crates.
+            for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
+                compiler_crates.extend(
+                    builder
+                        .in_tree_crates(root_crate, Some(target))
+                        .into_iter()
+                        .map(|krate| krate.name),
+                );
+            }
+        } else {
+            for root_crate in paths {
+                if !builder.src.join("compiler").join(&root_crate).exists() {
+                    builder.info(&format!(
+                        "\tskipping - compiler/{} (unknown compiler crate)",
+                        root_crate
+                    ));
+                } else {
+                    compiler_crates.extend(
+                        builder
+                            .in_tree_crates(root_crate, Some(target))
+                            .into_iter()
+                            .map(|krate| krate.name),
+                    );
+                }
+            }
         }
 
+        let mut to_open = None;
         for krate in &compiler_crates {
             // Create all crate output directories first to make sure rustdoc uses
             // relative links.
             // FIXME: Cargo should probably do this itself.
             t!(fs::create_dir_all(out_dir.join(krate)));
             cargo.arg("-p").arg(krate);
+            if to_open.is_none() {
+                to_open = Some(krate);
+            }
         }
 
         builder.run(&mut cargo.into());
+        // Let's open the first crate documentation page:
+        if let Some(krate) = to_open {
+            let index = out.join(krate).join("index.html");
+            open(builder, &index);
+        }
     }
 }
 
index d12e86b7c1deb1832e71510d1a5b6fd73059c666..386ffb384a81ee744d9201e516ce466800c92a61 100644 (file)
@@ -925,6 +925,11 @@ fn run(self, builder: &Builder<'_>) {
                     .env("RUSTDOC", builder.rustdoc(self.compiler))
                     .env("RUSTC", builder.rustc(self.compiler))
                     .current_dir(path);
+                // FIXME: implement a `// compile-flags` command or similar
+                //        instead of hard-coding this test
+                if entry.file_name() == "link_to_definition" {
+                    cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition");
+                }
                 builder.run(&mut cargo);
             }
         }
index c3a51e23859554369e6bbb5128dcef0e4f159fb5..4c76da9ddb4650203c129fceffdea95a3466c205 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c3a51e23859554369e6bbb5128dcef0e4f159fb5
+Subproject commit 4c76da9ddb4650203c129fceffdea95a3466c205
index 04f489c889235fe3b6dfe678ae5410d07deda958..9d4132b56c4999cd3ce1aeca5f1b2f2cb0d11c24 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 04f489c889235fe3b6dfe678ae5410d07deda958
+Subproject commit 9d4132b56c4999cd3ce1aeca5f1b2f2cb0d11c24
index 95f1acf9a39d6f402f654e917e2c1dfdb779c5fc..9198465b6ca8bed669df0cbb67c0e6d0b140803c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 95f1acf9a39d6f402f654e917e2c1dfdb779c5fc
+Subproject commit 9198465b6ca8bed669df0cbb67c0e6d0b140803c
index dce98abcf53d7a57e68b7e2b531616e2d4576bb3..b55db452f124c52708d94cdbafb1789d538aa80f 100644 (file)
@@ -222,13 +222,13 @@ all these files are linked from every page, changing where they are can be cumbe
 specially cache them. This flag will rename all these files in the output to include the suffix in
 the filename. For example, `light.css` would become `light-suf.css` with the above command.
 
-### `--display-warnings`: display warnings when documenting or running documentation tests
+### `--display-doctest-warnings`: display warnings when documenting or running documentation tests
 
 Using this flag looks like this:
 
 ```bash
-$ rustdoc src/lib.rs -Z unstable-options --display-warnings
-$ rustdoc --test src/lib.rs -Z unstable-options --display-warnings
+$ rustdoc src/lib.rs -Z unstable-options --display-doctest-warnings
+$ rustdoc --test src/lib.rs -Z unstable-options --display-doctest-warnings
 ```
 
 The intent behind this flag is to allow the user to see warnings that occur within their library or
diff --git a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md
new file mode 100644 (file)
index 0000000..977d258
--- /dev/null
@@ -0,0 +1,24 @@
+# `remap-cwd-prefix`
+
+The tracking issue for this feature is: [#87325](https://github.com/rust-lang/rust/issues/87325).
+
+------------------------
+
+This flag will rewrite absolute paths under the current working directory,
+replacing the current working directory prefix with a specified value.
+
+The given value may be absolute or relative, or empty. This switch takes
+precidence over `--remap-path-prefix` in case they would both match a given
+path.
+
+This flag helps to produce deterministic output, by removing the current working
+directory from build output, while allowing the command line to be universally
+reproducible, such that the same execution will work on all machines, regardless
+of build environment.
+
+## Example
+```sh
+# This would produce an absolute path to main.rs in build outputs of
+# "./main.rs".
+rustc -Z remap-cwd-prefix=. main.rs
+```
index 444b1cbf3cc45535d01a4f66a67c2ee4df84db76..ccaf6e8733e0c2e2987f8f58b7f2eb23fad3f23e 100644 (file)
@@ -804,9 +804,9 @@ The following ABIs can be used with `clobber_abi`:
 
 | Architecture | ABI name | Clobbered registers |
 | ------------ | -------- | ------------------- |
-| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `st([0-7])` |
-| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` |
-| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` |
+| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
+| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
+| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
 | AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x30`, `v[0-31]`, `p[0-15]`, `ffr` |
 | ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` |
 | RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` |
index 97930f106994a3a95df9fe2b1be22d098c0c97f6..ac440a395155c8af38184c533367193eecf73a93 100644 (file)
@@ -137,7 +137,7 @@ fn try_from(value: &str) -> Result<Self, Self::Error> {
     crate manual_passes: Vec<String>,
     /// Whether to display warnings during doc generation or while gathering doctests. By default,
     /// all non-rustdoc-specific lints are allowed when generating docs.
-    crate display_warnings: bool,
+    crate display_doctest_warnings: bool,
     /// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
     /// with and without documentation.
     crate show_coverage: bool,
@@ -192,7 +192,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             .field("persist_doctests", &self.persist_doctests)
             .field("default_passes", &self.default_passes)
             .field("manual_passes", &self.manual_passes)
-            .field("display_warnings", &self.display_warnings)
+            .field("display_doctest_warnings", &self.display_doctest_warnings)
             .field("show_coverage", &self.show_coverage)
             .field("crate_version", &self.crate_version)
             .field("render_options", &self.render_options)
@@ -632,7 +632,7 @@ fn println_condition(condition: Condition) {
         let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
         let playground_url = matches.opt_str("playground-url");
         let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
-        let display_warnings = matches.opt_present("display-warnings");
+        let display_doctest_warnings = matches.opt_present("display-doctest-warnings");
         let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
         let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
         let enable_minification = !matches.opt_present("disable-minification");
@@ -696,7 +696,7 @@ fn println_condition(condition: Condition) {
             test_args,
             default_passes,
             manual_passes,
-            display_warnings,
+            display_doctest_warnings,
             show_coverage,
             crate_version,
             test_run_directory,
index bd1d970fc199b6237515bb90518e28d643f2d748..d86b3b785d1127c721513807525f43a5e75baafe 100644 (file)
@@ -204,7 +204,6 @@ impl<'tcx> DocContext<'tcx> {
         lint_opts,
         describe_lints,
         lint_cap,
-        display_warnings,
         ..
     }: RustdocOptions,
 ) -> rustc_interface::Config {
@@ -237,7 +236,7 @@ impl<'tcx> DocContext<'tcx> {
         maybe_sysroot,
         search_paths: libs,
         crate_types,
-        lint_opts: if !display_warnings { lint_opts } else { vec![] },
+        lint_opts,
         lint_cap,
         cg: codegen_options,
         externs,
index 9b740acfcdfd7fe598e0e152e2e430008af5a58d..a5fab1b3d42170c7f7ccdd527dae9dca37820cf6 100644 (file)
@@ -11,7 +11,7 @@
 
 use std::fs;
 use std::io;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::string::ToString;
 use std::sync::mpsc::Sender;
 
@@ -55,17 +55,17 @@ impl DocFS {
         fs::create_dir_all(path)
     }
 
-    crate fn write<P, C, E>(&self, path: P, contents: C) -> Result<(), E>
+    crate fn write<E>(
+        &self,
+        path: PathBuf,
+        contents: impl 'static + Send + AsRef<[u8]>,
+    ) -> Result<(), E>
     where
-        P: AsRef<Path>,
-        C: AsRef<[u8]>,
         E: PathError,
     {
         if !self.sync_only && cfg!(windows) {
             // A possible future enhancement after more detailed profiling would
             // be to create the file sync so errors are reported eagerly.
-            let path = path.as_ref().to_path_buf();
-            let contents = contents.as_ref().to_vec();
             let sender = self.errors.clone().expect("can't write after closing");
             rayon::spawn(move || {
                 fs::write(&path, contents).unwrap_or_else(|e| {
index 9222a0338ae6fee7ae8bbb284f101ffe71354ace..dbeea9cddf3879af8b2ac43683d6e89dac7e199b 100644 (file)
@@ -40,7 +40,7 @@
     crate no_crate_inject: bool,
     /// Whether to emit compilation warnings when compiling doctests. Setting this will suppress
     /// the default `#![allow(unused)]`.
-    crate display_warnings: bool,
+    crate display_doctest_warnings: bool,
     /// Additional crate-level attributes to add to doctests.
     crate attrs: Vec<String>,
 }
@@ -72,7 +72,7 @@
         maybe_sysroot: options.maybe_sysroot.clone(),
         search_paths: options.libs.clone(),
         crate_types,
-        lint_opts: if !options.display_warnings { lint_opts } else { vec![] },
+        lint_opts: if !options.display_doctest_warnings { lint_opts } else { vec![] },
         lint_cap: Some(options.lint_cap.unwrap_or_else(|| lint::Forbid)),
         cg: options.codegen_options.clone(),
         externs: options.externs.clone(),
     };
 
     let test_args = options.test_args.clone();
-    let display_warnings = options.display_warnings;
+    let display_doctest_warnings = options.display_doctest_warnings;
     let nocapture = options.nocapture;
     let externs = options.externs.clone();
     let json_unused_externs = options.json_unused_externs;
                 let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
 
                 let mut opts = scrape_test_config(crate_attrs);
-                opts.display_warnings |= options.display_warnings;
+                opts.display_doctest_warnings |= options.display_doctest_warnings;
                 let enable_per_target_ignores = options.enable_per_target_ignores;
                 let mut collector = Collector::new(
                     tcx.crate_name(LOCAL_CRATE),
         Err(ErrorReported) => return Err(ErrorReported),
     };
 
-    run_tests(test_args, nocapture, display_warnings, tests);
+    run_tests(test_args, nocapture, display_doctest_warnings, tests);
 
     // Collect and warn about unused externs, but only if we've gotten
     // reports for each doctest
 crate fn run_tests(
     mut test_args: Vec<String>,
     nocapture: bool,
-    display_warnings: bool,
+    display_doctest_warnings: bool,
     tests: Vec<test::TestDescAndFn>,
 ) {
     test_args.insert(0, "rustdoctest".to_string());
     if nocapture {
         test_args.push("--nocapture".to_string());
     }
-    test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
+    test::test_main(
+        &test_args,
+        tests,
+        Some(test::Options::new().display_output(display_doctest_warnings)),
+    );
 }
 
 // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
@@ -224,7 +228,7 @@ fn scrape_test_config(attrs: &[ast::Attribute]) -> TestOptions {
     use rustc_ast_pretty::pprust;
 
     let mut opts =
-        TestOptions { no_crate_inject: false, display_warnings: false, attrs: Vec::new() };
+        TestOptions { no_crate_inject: false, display_doctest_warnings: false, attrs: Vec::new() };
 
     let test_attrs: Vec<_> = attrs
         .iter()
@@ -504,7 +508,7 @@ fn drop(&mut self) {
     let mut prog = String::new();
     let mut supports_color = false;
 
-    if opts.attrs.is_empty() && !opts.display_warnings {
+    if opts.attrs.is_empty() && !opts.display_doctest_warnings {
         // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
         // lints that are commonly triggered in doctests. The crate-level test attributes are
         // commonly used to make tests fail in case they trigger warnings, so having this there in
index c49e45c0e25a0410797cbceca32165998e8b87d1..1851708096564380e3fab75ca8a3c1617e33ae59 100644 (file)
@@ -52,7 +52,8 @@ fn main() {
 fn make_test_no_crate_inject() {
     // Even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
     // adding it anyway.
-    let opts = TestOptions { no_crate_inject: true, display_warnings: false, attrs: vec![] };
+    let opts =
+        TestOptions { no_crate_inject: true, display_doctest_warnings: false, attrs: vec![] };
     let input = "use asdf::qwop;
 assert_eq!(2+2, 4);";
     let expected = "#![allow(unused)]
@@ -215,10 +216,10 @@ fn make_test_dont_insert_main() {
 }
 
 #[test]
-fn make_test_display_warnings() {
+fn make_test_display_doctest_warnings() {
     // If the user is asking to display doctest warnings, suppress the default `allow(unused)`.
     let mut opts = TestOptions::default();
-    opts.display_warnings = true;
+    opts.display_doctest_warnings = true;
     let input = "assert_eq!(2+2, 4);";
     let expected = "fn main() {
 assert_eq!(2+2, 4);
index f8fc9243e14b95891549e9dd1b835f2e42cded95..ece3ee640e2a69a6f8193a4f2672032b87b8097c 100644 (file)
@@ -5,6 +5,7 @@
 //!
 //! Use the `render_with_highlighting` to highlight some rust code.
 
+use crate::clean::PrimitiveType;
 use crate::html::escape::Escape;
 use crate::html::render::Context;
 
@@ -584,6 +585,13 @@ fn string<T: Display>(
                             .ok()
                             .map(|(url, _, _)| url)
                     }
+                    LinkFromSrc::Primitive(prim) => format::href_with_root_path(
+                        PrimitiveType::primitive_locations(context.tcx())[&prim],
+                        context,
+                        Some(context_info.root_path),
+                    )
+                    .ok()
+                    .map(|(url, _, _)| url),
                 }
             })
         {
index 34f9c0a8187a659f5602dd580755e5242398adbc..b99d2fe5aa0d17584ca78cbba5e80ddf75f129d2 100644 (file)
@@ -574,7 +574,7 @@ fn after_krate(&mut self) -> Result<(), Error> {
             |buf: &mut Buffer| all.print(buf),
             &self.shared.style_files,
         );
-        self.shared.fs.write(final_file, v.as_bytes())?;
+        self.shared.fs.write(final_file, v)?;
 
         // Generating settings page.
         page.title = "Rustdoc settings";
@@ -596,14 +596,14 @@ fn after_krate(&mut self) -> Result<(), Error> {
             )?,
             &style_files,
         );
-        self.shared.fs.write(&settings_file, v.as_bytes())?;
+        self.shared.fs.write(settings_file, v)?;
         if let Some(ref redirections) = self.shared.redirections {
             if !redirections.borrow().is_empty() {
                 let redirect_map_path =
                     self.dst.join(&*crate_name.as_str()).join("redirect-map.json");
                 let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
                 self.shared.ensure_dir(&self.dst.join(&*crate_name.as_str()))?;
-                self.shared.fs.write(&redirect_map_path, paths.as_bytes())?;
+                self.shared.fs.write(redirect_map_path, paths)?;
             }
         }
 
@@ -641,7 +641,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
         if !buf.is_empty() {
             self.shared.ensure_dir(&self.dst)?;
             let joint_dst = self.dst.join("index.html");
-            scx.fs.write(&joint_dst, buf.as_bytes())?;
+            scx.fs.write(joint_dst, buf)?;
         }
 
         // Render sidebar-items.js used throughout this module.
@@ -653,7 +653,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
             let items = self.build_sidebar_items(module);
             let js_dst = self.dst.join("sidebar-items.js");
             let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap());
-            scx.fs.write(&js_dst, &v)?;
+            scx.fs.write(js_dst, v)?;
         }
         Ok(())
     }
@@ -687,7 +687,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
             let file_name = &item_path(item_type, &name.as_str());
             self.shared.ensure_dir(&self.dst)?;
             let joint_dst = self.dst.join(file_name);
-            self.shared.fs.write(&joint_dst, buf.as_bytes())?;
+            self.shared.fs.write(joint_dst, buf)?;
 
             if !self.render_redirect_pages {
                 self.shared.all.borrow_mut().append(full_path(self, &item), &item_type);
@@ -705,7 +705,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
                 } else {
                     let v = layout::redirect(file_name);
                     let redir_dst = self.dst.join(redir_name);
-                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
+                    self.shared.fs.write(redir_dst, v)?;
                 }
             }
         }
index 54476d9c9a459f19b34179f57caa25512baf5159..d517f3ac0e3a9e1a16db7d886a31dc263bedc90b 100644 (file)
@@ -1,4 +1,4 @@
-use crate::clean;
+use crate::clean::{self, PrimitiveType};
 use crate::html::sources;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -22,6 +22,7 @@
 crate enum LinkFromSrc {
     Local(clean::Span),
     External(DefId),
+    Primitive(PrimitiveType),
 }
 
 /// This function will do at most two things:
@@ -73,17 +74,20 @@ fn handle_path(&mut self, path: &rustc_hir::Path<'_>, path_span: Option<Span>) {
                 Some(def_id)
             }
             Res::Local(_) => None,
+            Res::PrimTy(p) => {
+                // FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
+                let span = path_span.unwrap_or(path.span);
+                self.matches.insert(span, LinkFromSrc::Primitive(PrimitiveType::from(p)));
+                return;
+            }
             Res::Err => return,
             _ => return,
         };
         if let Some(span) = self.tcx.hir().res_span(path.res) {
-            self.matches.insert(
-                path_span.unwrap_or_else(|| path.span),
-                LinkFromSrc::Local(clean::Span::new(span)),
-            );
-        } else if let Some(def_id) = info {
             self.matches
-                .insert(path_span.unwrap_or_else(|| path.span), LinkFromSrc::External(def_id));
+                .insert(path_span.unwrap_or(path.span), LinkFromSrc::Local(clean::Span::new(span)));
+        } else if let Some(def_id) = info {
+            self.matches.insert(path_span.unwrap_or(path.span), LinkFromSrc::External(def_id));
         }
     }
 }
index 99cd98f7eaeb84592f18d3287bc35f85cef10842..c1a83ad5820cb9067b329fc6590f783755198349 100644 (file)
@@ -105,10 +105,10 @@ fn suffix_path(&self, filename: &str) -> PathBuf {
         self.dst.join(&filename)
     }
 
-    fn write_shared<C: AsRef<[u8]>>(
+    fn write_shared(
         &self,
         resource: SharedResource<'_>,
-        contents: C,
+        contents: impl 'static + Send + AsRef<[u8]>,
         emit: &[EmitType],
     ) -> Result<(), Error> {
         if resource.should_emit(emit) {
@@ -121,25 +121,23 @@ fn write_shared<C: AsRef<[u8]>>(
     fn write_minify(
         &self,
         resource: SharedResource<'_>,
-        contents: &str,
+        contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
         minify: bool,
         emit: &[EmitType],
     ) -> Result<(), Error> {
-        let tmp;
-        let contents = if minify {
-            tmp = if resource.extension() == Some(&OsStr::new("css")) {
+        if minify {
+            let contents = contents.as_ref();
+            let contents = if resource.extension() == Some(&OsStr::new("css")) {
                 minifier::css::minify(contents).map_err(|e| {
                     Error::new(format!("failed to minify CSS file: {}", e), resource.path(self))
                 })?
             } else {
                 minifier::js::minify(contents)
             };
-            tmp.as_bytes()
+            self.write_shared(resource, contents, emit)
         } else {
-            contents.as_bytes()
-        };
-
-        self.write_shared(resource, contents, emit)
+            self.write_shared(resource, contents, emit)
+        }
     }
 }
 
@@ -155,15 +153,21 @@ pub(super) fn write_shared(
     let lock_file = cx.dst.join(".lock");
     let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file);
 
-    // The weird `: &_` is to work around a borrowck bug: https://github.com/rust-lang/rust/issues/41078#issuecomment-293646723
-    let write_minify = |p, c: &_| {
+    // Minified resources are usually toolchain resources. If they're not, they should use `cx.write_minify` directly.
+    fn write_minify(
+        basename: &'static str,
+        contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
+        cx: &Context<'_>,
+        options: &RenderOptions,
+    ) -> Result<(), Error> {
         cx.write_minify(
-            SharedResource::ToolchainSpecific { basename: p },
-            c,
+            SharedResource::ToolchainSpecific { basename },
+            contents,
             options.enable_minification,
             &options.emit,
         )
-    };
+    }
+
     // Toolchain resources should never be dynamic.
     let write_toolchain = |p: &'static _, c: &'static _| {
         cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit)
@@ -210,12 +214,12 @@ fn add_background_image_to_css(
         "details.undocumented > summary::before, details.rustdoc-toggle > summary::before",
         "toggle-plus.svg",
     );
-    write_minify("rustdoc.css", &rustdoc_css)?;
+    write_minify("rustdoc.css", rustdoc_css, cx, options)?;
 
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
-    write_minify("settings.css", static_files::SETTINGS_CSS)?;
-    write_minify("noscript.css", static_files::NOSCRIPT_CSS)?;
+    write_minify("settings.css", static_files::SETTINGS_CSS, cx, options)?;
+    write_minify("noscript.css", static_files::NOSCRIPT_CSS, cx, options)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
@@ -228,9 +232,9 @@ fn add_background_image_to_css(
 
         // Handle the official themes
         match theme {
-            "light" => write_minify("light.css", static_files::themes::LIGHT)?,
-            "dark" => write_minify("dark.css", static_files::themes::DARK)?,
-            "ayu" => write_minify("ayu.css", static_files::themes::AYU)?,
+            "light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?,
+            "dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?,
+            "ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?,
             _ => {
                 // Handle added third-party themes
                 let filename = format!("{}.{}", theme, extension);
@@ -264,26 +268,38 @@ fn add_background_image_to_css(
     // Maybe we can change the representation to move this out of main.js?
     write_minify(
         "main.js",
-        &static_files::MAIN_JS.replace(
-            "/* INSERT THEMES HERE */",
-            &format!(" = {}", serde_json::to_string(&themes).unwrap()),
-        ),
+        static_files::MAIN_JS
+            .replace(
+                "/* INSERT THEMES HERE */",
+                &format!(" = {}", serde_json::to_string(&themes).unwrap()),
+            )
+            .replace(
+                "/* INSERT RUSTDOC_VERSION HERE */",
+                &format!(
+                    "rustdoc {}",
+                    rustc_interface::util::version_str().unwrap_or("unknown version")
+                ),
+            ),
+        cx,
+        options,
     )?;
-    write_minify("search.js", static_files::SEARCH_JS)?;
-    write_minify("settings.js", static_files::SETTINGS_JS)?;
+    write_minify("search.js", static_files::SEARCH_JS, cx, options)?;
+    write_minify("settings.js", static_files::SETTINGS_JS, cx, options)?;
 
     if cx.include_sources {
-        write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT)?;
+        write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT, cx, options)?;
     }
 
     {
         write_minify(
             "storage.js",
-            &format!(
+            format!(
                 "var resourcesSuffix = \"{}\";{}",
                 cx.shared.resource_suffix,
                 static_files::STORAGE_JS
             ),
+            cx,
+            options,
         )?;
     }
 
@@ -292,12 +308,12 @@ fn add_background_image_to_css(
         // This varies based on the invocation, so it can't go through the write_minify wrapper.
         cx.write_minify(
             SharedResource::InvocationSpecific { basename: "theme.css" },
-            &buffer,
+            buffer,
             options.enable_minification,
             &options.emit,
         )?;
     }
-    write_minify("normalize.css", static_files::NORMALIZE_CSS)?;
+    write_minify("normalize.css", static_files::NORMALIZE_CSS, cx, options)?;
     for (name, contents) in &*FILES_UNVERSIONED {
         cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?;
     }
@@ -512,7 +528,7 @@ fn to_json_string(&self) -> String {
                 content,
                 &cx.shared.style_files,
             );
-            cx.shared.fs.write(&dst, v.as_bytes())?;
+            cx.shared.fs.write(dst, v)?;
         }
     }
 
@@ -603,7 +619,7 @@ struct Implementor {
              }",
         );
         v.push_str("})()");
-        cx.shared.fs.write(&mydst, &v)?;
+        cx.shared.fs.write(mydst, v)?;
     }
     Ok(())
 }
index bb90b195ddd4f5547dfc9c19d79a12cac53736ec..71c64231a210eb48e92e2b7739b7bc08362df134 100644 (file)
@@ -208,7 +208,7 @@ fn emit_source(
             },
             &self.cx.shared.style_files,
         );
-        self.cx.shared.fs.write(&cur, v.as_bytes())?;
+        self.cx.shared.fs.write(cur, v)?;
         self.emitted_local_sources.insert(p);
         Ok(())
     }
index 2d4bfc62af68e94e5fa26c8c14ba306b2953a903..eb7cc9309f41641c6212ca6e244e8ad6fd5b43ef 100644 (file)
@@ -928,15 +928,24 @@ body.blur > :not(#help) {
        display: block;
        margin-right: 0.5rem;
 }
-#help > div > span {
+#help span.top, #help span.bottom {
        text-align: center;
        display: block;
-       margin: 10px 0;
        font-size: 18px;
-       border-bottom: 1px solid #ccc;
+
+}
+#help span.top {
+       text-align: center;
+       display: block;
+       margin: 10px 0;
+       border-bottom: 1px solid;
        padding-bottom: 4px;
        margin-bottom: 6px;
 }
+#help span.bottom {
+       clear: both;
+       border-top: 1px solid;
+}
 #help dd { margin: 5px 35px; }
 #help .infos { padding-left: 0; }
 #help h1, #help h2 { margin-top: 0; }
index f9ddef4120bbec8c69c0ba92ab2f3c854850f976..c79801e830876f77c0720756da2c3fa398052e13 100644 (file)
@@ -217,7 +217,7 @@ a {
        color: #c5c5c5;
 }
 body.source .example-wrap pre.rust a {
-       background: #c5c5c5;
+       background: #333;
 }
 
 .docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
@@ -286,8 +286,8 @@ details.undocumented > summary::before {
        border-radius: 4px;
 }
 
-#help > div > span {
-       border-bottom-color: #5c6773;
+#help span.bottom, #help span.top {
+       border-color: #5c6773;
 }
 
 .since {
index d9348be6994e2a1d676cf3b8a6ea9c6e8ea57af0..d2e54070acd68621efadf5e506c9ffb9806aed1c 100644 (file)
@@ -242,8 +242,8 @@ details.undocumented > summary::before {
        border-color: #bfbfbf;
 }
 
-#help > div > span {
-       border-bottom-color: #bfbfbf;
+#help span.bottom, #help span.top {
+       border-color: #bfbfbf;
 }
 
 #help dt {
index 0ffe5929ea59376e14b0da7948a7de273cac808d..25d810560c1469b98397fd2975ad686c82c1165a 100644 (file)
@@ -232,8 +232,8 @@ details.undocumented > summary::before {
        border-color: #bfbfbf;
 }
 
-#help > div > span {
-       border-bottom-color: #bfbfbf;
+#help span.bottom, #help span.top {
+       border-color: #bfbfbf;
 }
 
 .since {
index 1eebd39256459e1e834f31022f6a32f2afb27cc0..e396fd9d288db1cc34da37279113f4a65683b0c7 100644 (file)
@@ -911,6 +911,7 @@ function hideThemeButtonState() {
         });
 
         var book_info = document.createElement("span");
+        book_info.className = "top";
         book_info.innerHTML = "You can find more information in \
             <a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
 
@@ -961,6 +962,14 @@ function hideThemeButtonState() {
         container.appendChild(div_shortcuts);
         container.appendChild(div_infos);
 
+        var rustdoc_version = document.createElement("span");
+        rustdoc_version.className = "bottom";
+        var rustdoc_version_code = document.createElement("code");
+        rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */";
+        rustdoc_version.appendChild(rustdoc_version_code);
+
+        container.appendChild(rustdoc_version);
+
         popup.appendChild(container);
         insertAfter(popup, searchState.outputElement());
         // So that it's only built once and then it'll do nothing when called!
index 8246834a74688040d3dc089d7cbefc3460b99d30..f170561300cc2d6ef780b4ce0dde10286ab2aa00 100644 (file)
@@ -419,8 +419,12 @@ fn opts() -> Vec<RustcOptGroup> {
                 "URL",
             )
         }),
-        unstable("display-warnings", |o| {
-            o.optflagmulti("", "display-warnings", "to print code warnings when testing doc")
+        unstable("display-doctest-warnings", |o| {
+            o.optflagmulti(
+                "",
+                "display-doctest-warnings",
+                "show warnings that originate in doctests",
+            )
         }),
         stable("crate-version", |o| {
             o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
index 80af2a7aaf5c8ab820ef593534f023a9dc22d073..2ae4897dc349625ede4dad13463a0c876eb26e08 100644 (file)
@@ -120,7 +120,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
         .map_err(|err| format!("{}: {}", options.input.display(), err))?;
     let mut opts = TestOptions::default();
     opts.no_crate_inject = true;
-    opts.display_warnings = options.display_warnings;
+    opts.display_doctest_warnings = options.display_doctest_warnings;
     let mut collector = Collector::new(
         Symbol::intern(&options.input.display().to_string()),
         options.clone(),
@@ -138,7 +138,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
     crate::doctest::run_tests(
         options.test_args,
         options.nocapture,
-        options.display_warnings,
+        options.display_doctest_warnings,
         collector.tests,
     );
     Ok(())
index 1b5ec1b08fab04d5383025922c2b5517858523d9..279d0dbda82ee7b45378181870f882768106c245 100644 (file)
@@ -96,6 +96,7 @@ fn add_test(&mut self, _: String, config: LangString, _: usize) {
 
     if cx.tcx.hir().attrs(hir_id).lists(sym::doc).has_word(sym::hidden)
         || inherits_doc_hidden(cx.tcx, hir_id)
+        || cx.tcx.hir().span(hir_id).in_derive_expansion()
     {
         return false;
     }
index 40bea30f1252ca853d300202ae31eeb532b206ae..4a529541bae60734236b0d380a72aa074a526fd0 100644 (file)
@@ -3,6 +3,8 @@
 // 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 ==================================================================================
 //
diff --git a/src/test/pretty/anonymous-types.rs b/src/test/pretty/anonymous-types.rs
deleted file mode 100644 (file)
index 5ff452e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Test for issue 85480
-// Pretty print anonymous struct and union types
-
-// pp-exact
-// pretty-compare-only
-
-struct Foo {
-    _: union {
-           _: struct {
-                  a: u8,
-                  b: u16,
-              },
-           c: u32,
-       },
-    d: u64,
-    e: f32,
-}
-
-type A =
- struct {
-     field: u8,
- };
-
-fn main() { }
index a17ec212cfd58250f3185c1d2302c00bf9eb7e84..adccc153568485f0fc62124c2f60e107d87ae3ea 100644 (file)
@@ -9,9 +9,19 @@ all:  \
        opt \
        link_paths \
        remap_paths \
-       different_source_dirs \
+       different_source_dirs_rlib \
+       remap_cwd_rlib \
+       remap_cwd_to_empty \
        extern_flags
 
+# TODO: Builds of `bin` crate types are not deterministic with debuginfo=2 on
+# Windows.
+# See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533
+# Issue: https://github.com/rust-lang/rust/issues/88982
+#
+#      different_source_dirs_bin \
+#      remap_cwd_bin \
+
 smoke:
        rm -rf $(TMPDIR) && mkdir $(TMPDIR)
        $(RUSTC) linker.rs -O
@@ -52,7 +62,19 @@ remap_paths:
        $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/b=/c
        cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
 
-different_source_dirs:
+different_source_dirs_bin:
+       rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+       $(RUSTC) reproducible-build-aux.rs
+       mkdir $(TMPDIR)/test
+       cp reproducible-build.rs $(TMPDIR)/test
+       $(RUSTC) reproducible-build.rs --crate-type bin --remap-path-prefix=$$PWD=/b
+       cp $(TMPDIR)/reproducible-build $(TMPDIR)/foo
+       (cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \
+               --remap-path-prefix=$(TMPDIR)/test=/b \
+               --crate-type bin)
+       cmp "$(TMPDIR)/reproducible-build" "$(TMPDIR)/foo" || exit 1
+
+different_source_dirs_rlib:
        rm -rf $(TMPDIR) && mkdir $(TMPDIR)
        $(RUSTC) reproducible-build-aux.rs
        mkdir $(TMPDIR)/test
@@ -64,6 +86,45 @@ different_source_dirs:
                --crate-type rlib)
        cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
 
+remap_cwd_bin:
+       rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+       $(RUSTC) reproducible-build-aux.rs
+       mkdir $(TMPDIR)/test
+       cp reproducible-build.rs $(TMPDIR)/test
+       $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \
+         -Z remap-cwd-prefix=.
+       cp $(TMPDIR)/reproducible-build $(TMPDIR)/first
+       (cd $(TMPDIR)/test && \
+        $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \
+          -Z remap-cwd-prefix=.)
+       cmp "$(TMPDIR)/first" "$(TMPDIR)/reproducible-build" || exit 1
+
+remap_cwd_rlib:
+       rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+       $(RUSTC) reproducible-build-aux.rs
+       mkdir $(TMPDIR)/test
+       cp reproducible-build.rs $(TMPDIR)/test
+       $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+         -Z remap-cwd-prefix=.
+       cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib
+       (cd $(TMPDIR)/test && \
+        $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+          -Z remap-cwd-prefix=.)
+       cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1
+
+remap_cwd_to_empty:
+       rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+       $(RUSTC) reproducible-build-aux.rs
+       mkdir $(TMPDIR)/test
+       cp reproducible-build.rs $(TMPDIR)/test
+       $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+         -Z remap-cwd-prefix=
+       cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib
+       (cd $(TMPDIR)/test && \
+        $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \
+          -Z remap-cwd-prefix=)
+       cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1
+
 extern_flags:
        rm -rf $(TMPDIR) && mkdir $(TMPDIR)
        $(RUSTC) reproducible-build-aux.rs
index f479bdabb9c0c67313bfe2632114c5a9de4fd84e..cb77eb34fef08d77246fe41bdf4eec42d9be6b78 100644 (file)
@@ -17,6 +17,17 @@ def convert_to_string(s):
     return s
 
 
+def set_ld_lib_path():
+    var = os.environ.get("LD_LIB_PATH_ENVVAR")
+    rpath = os.environ.get("HOST_RPATH_DIR")
+    if var and rpath:
+        path = os.environ.get(var)
+        if path:
+            os.environ[var] = rpath + os.pathsep + path
+        else:
+            os.environ[var] = rpath
+
+
 def exec_command(command, to_input=None):
     child = None
     if to_input is None:
@@ -50,7 +61,9 @@ def get_all_libs(dir_path):
             if isfile(join(dir_path, f)) and f.endswith('.rlib') and f not in STABLE_CRATES]
 
 
+set_ld_lib_path()
 sysroot = exec_command([os.environ['RUSTC'], '--print', 'sysroot'])[0].replace('\n', '')
+assert sysroot, "Could not read the rustc sysroot!"
 libs = get_all_libs(join(sysroot, 'lib/rustlib/{}/lib'.format(os.environ['TARGET'])))
 
 ret = 0
index 00326e9bbc4ccfd5d8cae0ea5182ba5958cf1fc1..6fb92e196602e399c87a8746a3d7d38809cf66b2 100644 (file)
@@ -1,5 +1,6 @@
 goto: file://|DOC_PATH|/test_docs/index.html
 click: ".srclink"
+wait-for: "#sidebar-toggle"
 click: "#sidebar-toggle"
 wait-for: 500
 fail: true
diff --git a/src/test/rustdoc-gui/jump-to-def-background.goml b/src/test/rustdoc-gui/jump-to-def-background.goml
new file mode 100644 (file)
index 0000000..3df899e
--- /dev/null
@@ -0,0 +1,23 @@
+// We check the background color on the jump to definition links in the source code page.
+goto: file://|DOC_PATH|/src/link_to_definition/lib.rs.html
+
+// Set the theme to dark.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(51, 51, 51)"}, ALL)
+
+// Set the theme to ayu.
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(51, 51, 51)"}, ALL)
+
+// Set the theme to light.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(238, 238, 238)"}, ALL)
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock b/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
new file mode 100644 (file)
index 0000000..e4b4e52
--- /dev/null
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "link_to_definition"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml b/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
new file mode 100644 (file)
index 0000000..cdd294d
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "link_to_definition"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/lib.rs b/src/test/rustdoc-gui/src/link_to_definition/lib.rs
new file mode 100644 (file)
index 0000000..de9ee66
--- /dev/null
@@ -0,0 +1,6 @@
+pub struct Bar {
+    pub a: String,
+    pub b: u32,
+}
+
+pub fn foo(_b: &Bar) {}
diff --git a/src/test/rustdoc-ui/display-output.rs b/src/test/rustdoc-ui/display-output.rs
new file mode 100644 (file)
index 0000000..5e39002
--- /dev/null
@@ -0,0 +1,9 @@
+// check-pass
+// compile-flags:-Zunstable-options --display-doctest-warnings --test
+// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
+// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
+
+/// ```
+/// let x = 12;
+/// ```
+pub fn foo() {}
diff --git a/src/test/rustdoc-ui/display-output.stdout b/src/test/rustdoc-ui/display-output.stdout
new file mode 100644 (file)
index 0000000..00467b9
--- /dev/null
@@ -0,0 +1,24 @@
+
+running 1 test
+test $DIR/display-output.rs - foo (line 6) ... ok
+
+successes:
+
+---- $DIR/display-output.rs - foo (line 6) stdout ----
+warning: unused variable: `x`
+  --> $DIR/display-output.rs:7:5
+   |
+LL | let x = 12;
+   |     ^ help: if this is intentional, prefix it with an underscore: `_x`
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
+
+
+successes:
+    $DIR/display-output.rs - foo (line 6)
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
index 7dd2ebfedbbd74b605c4898488da526ae71ddd39..fac6342cd24b9e86da8152b50c1e574e7d9b4973 100644 (file)
@@ -78,6 +78,15 @@ fn clone(&self) -> Self {
 }
 
 
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+#[derive(Clone)]
+pub struct NiceStruct;
+
 #[doc(hidden)]
 pub mod foo {
     pub fn bar() {}
diff --git a/src/test/rustdoc/check-source-code-urls-to-def-std.rs b/src/test/rustdoc/check-source-code-urls-to-def-std.rs
new file mode 100644 (file)
index 0000000..b129ceb
--- /dev/null
@@ -0,0 +1,17 @@
+// compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+// @has 'src/foo/check-source-code-urls-to-def-std.rs.html'
+
+fn babar() {}
+
+// @has - '//a[@href="{{channel}}/std/primitive.u32.html"]' 'u32'
+// @has - '//a[@href="{{channel}}/std/primitive.str.html"]' 'str'
+// @has - '//a[@href="{{channel}}/std/primitive.bool.html"]' 'bool'
+// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#7"]' 'babar'
+pub fn foo(a: u32, b: &str, c: String) {
+    let x = 12;
+    let y: bool = true;
+    babar();
+}
index e3ae79ccdb17ad52effb5bdc8d04ec2da9a0daa8..0cb8e4230166ff0d2484afd7e8142479938bcce9 100644 (file)
@@ -27,6 +27,8 @@ fn hello(&self) {}
 fn babar() {}
 
 // @has - '//a/@href' '/struct.String.html'
+// @has - '//a/@href' '/primitive.u32.html'
+// @has - '//a/@href' '/primitive.str.html'
 // @count - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#21"]' 5
 // @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
 pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
@@ -40,5 +42,9 @@ pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::Sour
 
 // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14-16"]' 'bar::sub::Trait'
 // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14-16"]' 'Trait'
-pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V) {
+pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {
 }
+
+// @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool'
+#[doc(primitive = "bool")]
+mod whatever {}
index 7b4594108246b9b1eec19431cf5cd22ac97f7435..fc949f24948574619af48ab1e4a0ddd21541bea7 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object
 LL | impl dyn Trait {
    |      ^^^^^^^^^ `Trait` cannot be made into an object
    |
-   = help: consider moving `N` to another trait
 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/associated-const-in-trait.rs:6:11
    |
@@ -12,6 +11,7 @@ LL | trait Trait {
    |       ----- this trait cannot be made into an object...
 LL |     const N: usize;
    |           ^ ...because it contains this associated `const`
+   = help: consider moving `N` to another trait
 
 error: aborting due to previous error
 
index 77915a80a79b07713b60cd863739a309aa3be642..7b158f1d754740ad1500dbaf5f7146e48085e045 100644 (file)
@@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | impl dyn Bar {}
    |      ^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `X` to another trait
 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/issue-48027.rs:2:11
    |
@@ -29,6 +28,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     const X: usize;
    |           ^ ...because it contains this associated `const`
+   = help: consider moving `X` to another trait
 
 error: aborting due to 2 previous errors
 
index edcd2bf85adb64cc932e0914afc746faa7ce2ecb..e66c6b35ca1eed0749a494c4f95d889d19c8fea6 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
   --> $DIR/associated-types-bound-failure.rs:19:19
    |
 LL |     ToInt::to_int(&g.get())
-   |                   ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
+   |     ------------- ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by `ToInt::to_int`
   --> $DIR/associated-types-bound-failure.rs:6:5
index c993e1d27202d5a53ac33f843623d48b8bd24852..912dedfdcebbc3b220401347f2191c494eb02f5a 100644 (file)
@@ -28,13 +28,11 @@ pub fn f1_int_uint() {
 pub fn f1_uint_uint() {
     f1(2u32, 4u32);
     //~^ ERROR `u32: Foo` is not satisfied
-    //~| ERROR `u32: Foo` is not satisfied
 }
 
 pub fn f1_uint_int() {
     f1(2u32, 4i32);
     //~^ ERROR `u32: Foo` is not satisfied
-    //~| ERROR `u32: Foo` is not satisfied
 }
 
 pub fn f2_int() {
index 8d919190532cfb02eb3e22c9ca22e323375a8eda..15a5245d54d9577c52a6350962400918138c6670 100644 (file)
@@ -10,10 +10,12 @@ LL |     f1(2i32, 4u32);
    |               ~~~
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:29:5
+  --> $DIR/associated-types-path-2.rs:29:14
    |
 LL |     f1(2u32, 4u32);
-   |     ^^ the trait `Foo` is not implemented for `u32`
+   |     --       ^^^^ the trait `Foo` is not implemented for `u32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f1`
   --> $DIR/associated-types-path-2.rs:13:14
@@ -22,16 +24,12 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
    |              ^^^ required by this bound in `f1`
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:29:5
-   |
-LL |     f1(2u32, 4u32);
-   |     ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
-
-error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:35:5
+  --> $DIR/associated-types-path-2.rs:34:14
    |
 LL |     f1(2u32, 4i32);
-   |     ^^ the trait `Foo` is not implemented for `u32`
+   |     --       ^^^^ the trait `Foo` is not implemented for `u32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f1`
   --> $DIR/associated-types-path-2.rs:13:14
@@ -39,14 +37,8 @@ note: required by a bound in `f1`
 LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
    |              ^^^ required by this bound in `f1`
 
-error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:35:5
-   |
-LL |     f1(2u32, 4i32);
-   |     ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
-
 error[E0308]: mismatched types
-  --> $DIR/associated-types-path-2.rs:41:18
+  --> $DIR/associated-types-path-2.rs:39:18
    |
 LL |     let _: i32 = f2(2i32);
    |            ---   ^^^^^^^^ expected `i32`, found `u32`
@@ -58,7 +50,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn
 LL |     let _: i32 = f2(2i32).try_into().unwrap();
    |                          ++++++++++++++++++++
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-19883.rs b/src/test/ui/associated-types/issue-19883.rs
new file mode 100644 (file)
index 0000000..5cf4220
--- /dev/null
@@ -0,0 +1,16 @@
+trait From<Src> {
+    type Output;
+
+    fn from(src: Src) -> <Self as From<Src>>::Output;
+}
+
+trait To: Sized {
+    fn to<Dst: From<Self>>(self) ->
+        <Dst as From<Self>>::Dst
+        //~^ ERROR cannot find associated type `Dst` in trait `From`
+    {
+        From::from(self)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-19883.stderr b/src/test/ui/associated-types/issue-19883.stderr
new file mode 100644 (file)
index 0000000..bd6a86b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0576]: cannot find associated type `Dst` in trait `From`
+  --> $DIR/issue-19883.rs:9:30
+   |
+LL |     type Output;
+   |     ------------ associated type `Output` defined here
+...
+LL |         <Dst as From<Self>>::Dst
+   |                              ^^^
+   |                              |
+   |                              not found in `From`
+   |                              help: maybe you meant this associated type: `Output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0576`.
diff --git a/src/test/ui/associated-types/issue-21363.rs b/src/test/ui/associated-types/issue-21363.rs
new file mode 100644 (file)
index 0000000..acc28cb
--- /dev/null
@@ -0,0 +1,15 @@
+// check-pass
+// pretty-expanded FIXME #23616
+
+#![no_implicit_prelude]
+
+trait Iterator {
+    type Item;
+    fn dummy(&self) { }
+}
+
+impl<'a, T> Iterator for &'a mut (dyn Iterator<Item=T> + 'a) {
+    type Item = T;
+}
+
+fn main() {}
index e36572740f6551b39081018dacde8ca49ed120c8..22daaf329102a5a7624c5b71634cfb7c6bdab1d9 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
   --> $DIR/issue-27675-unchecked-bounds.rs:15:31
    |
 LL |     copy::<dyn Setup<From=T>>(t)
-   |                               ^ the trait `Copy` is not implemented for `T`
+   |     ------------------------- ^ the trait `Copy` is not implemented for `T`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `copy`
   --> $DIR/issue-27675-unchecked-bounds.rs:10:12
diff --git a/src/test/ui/async-await/auxiliary/issue-72470-lib.rs b/src/test/ui/async-await/auxiliary/issue-72470-lib.rs
new file mode 100644 (file)
index 0000000..8383eba
--- /dev/null
@@ -0,0 +1,175 @@
+// compile-flags: -C opt-level=3
+// edition:2018
+
+use std::future::Future;
+use std::marker::PhantomData;
+use std::pin::Pin;
+use std::sync::atomic::AtomicUsize;
+use std::sync::Arc;
+use std::task::Poll::{Pending, Ready};
+use std::task::Waker;
+use std::task::{Context, Poll};
+use std::{
+    ptr,
+    task::{RawWaker, RawWakerVTable},
+};
+
+/// Future for the [`poll_fn`] function.
+pub struct PollFn<F> {
+    f: F,
+}
+
+impl<F> Unpin for PollFn<F> {}
+
+/// Creates a new future wrapping around a function returning [`Poll`].
+pub fn poll_fn<T, F>(f: F) -> PollFn<F>
+where
+    F: FnMut(&mut Context<'_>) -> Poll<T>,
+{
+    PollFn { f }
+}
+
+impl<T, F> Future for PollFn<F>
+where
+    F: FnMut(&mut Context<'_>) -> Poll<T>,
+{
+    type Output = T;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
+        (&mut self.f)(cx)
+    }
+}
+pub fn run<F: Future>(future: F) -> F::Output {
+    BasicScheduler.block_on(future)
+}
+
+pub(crate) struct BasicScheduler;
+
+impl BasicScheduler {
+    pub(crate) fn block_on<F>(&mut self, mut future: F) -> F::Output
+    where
+        F: Future,
+    {
+        let waker = unsafe { Waker::from_raw(raw_waker()) };
+        let mut cx = std::task::Context::from_waker(&waker);
+
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+
+        loop {
+            if let Ready(v) = future.as_mut().poll(&mut cx) {
+                return v;
+            }
+        }
+    }
+}
+
+// ===== impl Spawner =====
+
+fn raw_waker() -> RawWaker {
+    RawWaker::new(ptr::null(), waker_vtable())
+}
+
+fn waker_vtable() -> &'static RawWakerVTable {
+    &RawWakerVTable::new(
+        clone_arc_raw,
+        wake_arc_raw,
+        wake_by_ref_arc_raw,
+        drop_arc_raw,
+    )
+}
+
+unsafe fn clone_arc_raw(_: *const ()) -> RawWaker {
+    raw_waker()
+}
+
+unsafe fn wake_arc_raw(_: *const ()) {}
+
+unsafe fn wake_by_ref_arc_raw(_: *const ()) {}
+
+unsafe fn drop_arc_raw(_: *const ()) {}
+
+struct AtomicWaker {}
+
+impl AtomicWaker {
+    /// Create an `AtomicWaker`
+    fn new() -> AtomicWaker {
+        AtomicWaker {}
+    }
+
+    fn register_by_ref(&self, _waker: &Waker) {}
+}
+
+#[allow(dead_code)]
+struct Tx<T> {
+    inner: Arc<Chan<T>>,
+}
+
+struct Rx<T> {
+    inner: Arc<Chan<T>>,
+}
+
+#[allow(dead_code)]
+struct Chan<T> {
+    tx: PhantomData<T>,
+    semaphore: Sema,
+    rx_waker: AtomicWaker,
+    rx_closed: bool,
+}
+
+fn channel<T>() -> (Tx<T>, Rx<T>) {
+    let chan = Arc::new(Chan {
+        tx: PhantomData,
+        semaphore: Sema(AtomicUsize::new(0)),
+        rx_waker: AtomicWaker::new(),
+        rx_closed: false,
+    });
+
+    (
+        Tx {
+            inner: chan.clone(),
+        },
+        Rx { inner: chan },
+    )
+}
+
+// ===== impl Rx =====
+
+impl<T> Rx<T> {
+    /// Receive the next value
+    fn recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<T>> {
+        self.inner.rx_waker.register_by_ref(cx.waker());
+
+        if self.inner.rx_closed && self.inner.semaphore.is_idle() {
+            Ready(None)
+        } else {
+            Pending
+        }
+    }
+}
+
+struct Sema(AtomicUsize);
+
+impl Sema {
+    fn is_idle(&self) -> bool {
+        false
+    }
+}
+
+pub struct UnboundedReceiver<T> {
+    chan: Rx<T>,
+}
+
+pub fn unbounded_channel<T>() -> UnboundedReceiver<T> {
+    let (tx, rx) = channel();
+
+    drop(tx);
+    let rx = UnboundedReceiver { chan: rx };
+
+    rx
+}
+
+impl<T> UnboundedReceiver<T> {
+    pub async fn recv(&mut self) -> Option<T> {
+        poll_fn(|cx| self.chan.recv(cx)).await
+    }
+}
index b79b6bc449233ab86c1a1f8cbb1b763ffc457021..919abf646037deaa2bcd7ceae1f8aa14e4214d1f 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Option<&str>: AsRef<Path>` is not satisfied
   --> $DIR/issue-72442.rs:12:36
    |
 LL |             let mut f = File::open(path.to_str())?;
-   |                                    ^^^^^^^^^^^^^ the trait `AsRef<Path>` is not implemented for `Option<&str>`
+   |                         ---------- ^^^^^^^^^^^^^ the trait `AsRef<Path>` is not implemented for `Option<&str>`
+   |                         |
+   |                         required by a bound introduced by this call
    |
 note: required by a bound in `File::open`
   --> $SRC_DIR/std/src/fs.rs:LL:COL
diff --git a/src/test/ui/async-await/issue-72470-llvm-dominate.rs b/src/test/ui/async-await/issue-72470-llvm-dominate.rs
new file mode 100644 (file)
index 0000000..5bb69a0
--- /dev/null
@@ -0,0 +1,66 @@
+// compile-flags: -C opt-level=3
+// aux-build: issue-72470-lib.rs
+// edition:2018
+// build-pass
+
+// Regression test for issue #72470, using the minimization
+// in https://github.com/jonas-schievink/llvm-error
+
+extern crate issue_72470_lib;
+
+use std::future::Future;
+use std::pin::Pin;
+use std::sync::Mutex;
+use std::task::Poll::{Pending, Ready};
+
+#[allow(dead_code)]
+enum Msg {
+    A(Vec<()>),
+    B,
+}
+
+#[allow(dead_code)]
+enum Out {
+    _0(Option<Msg>),
+    Disabled,
+}
+
+#[allow(unused_must_use)]
+fn main() {
+    let mut rx = issue_72470_lib::unbounded_channel::<Msg>();
+    let entity = Mutex::new(());
+    issue_72470_lib::run(async move {
+        {
+            let output = {
+                let mut fut = rx.recv();
+                issue_72470_lib::poll_fn(|cx| {
+                    loop {
+                        let fut = unsafe { Pin::new_unchecked(&mut fut) };
+                        let out = match fut.poll(cx) {
+                            Ready(out) => out,
+                            Pending => {
+                                break;
+                            }
+                        };
+                        #[allow(unused_variables)]
+                        match &out {
+                            Some(_msg) => {}
+                            _ => break,
+                        }
+                        return Ready(Out::_0(out));
+                    }
+                    Ready(Out::_0(None))
+                })
+                .await
+            };
+            match output {
+                Out::_0(Some(_msg)) => {
+                    entity.lock();
+                }
+                Out::_0(None) => unreachable!(),
+                _ => unreachable!(),
+            }
+        }
+        entity.lock();
+    });
+}
diff --git a/src/test/ui/auxiliary/define-macro.rs b/src/test/ui/auxiliary/define-macro.rs
deleted file mode 100644 (file)
index 4956907..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#[macro_export]
-macro_rules! define_macro {
-    ($i:ident) => {
-        macro_rules! $i { () => {} }
-    }
-}
diff --git a/src/test/ui/auxiliary/issue-72470-lib.rs b/src/test/ui/auxiliary/issue-72470-lib.rs
deleted file mode 100644 (file)
index 8383eba..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-// compile-flags: -C opt-level=3
-// edition:2018
-
-use std::future::Future;
-use std::marker::PhantomData;
-use std::pin::Pin;
-use std::sync::atomic::AtomicUsize;
-use std::sync::Arc;
-use std::task::Poll::{Pending, Ready};
-use std::task::Waker;
-use std::task::{Context, Poll};
-use std::{
-    ptr,
-    task::{RawWaker, RawWakerVTable},
-};
-
-/// Future for the [`poll_fn`] function.
-pub struct PollFn<F> {
-    f: F,
-}
-
-impl<F> Unpin for PollFn<F> {}
-
-/// Creates a new future wrapping around a function returning [`Poll`].
-pub fn poll_fn<T, F>(f: F) -> PollFn<F>
-where
-    F: FnMut(&mut Context<'_>) -> Poll<T>,
-{
-    PollFn { f }
-}
-
-impl<T, F> Future for PollFn<F>
-where
-    F: FnMut(&mut Context<'_>) -> Poll<T>,
-{
-    type Output = T;
-
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
-        (&mut self.f)(cx)
-    }
-}
-pub fn run<F: Future>(future: F) -> F::Output {
-    BasicScheduler.block_on(future)
-}
-
-pub(crate) struct BasicScheduler;
-
-impl BasicScheduler {
-    pub(crate) fn block_on<F>(&mut self, mut future: F) -> F::Output
-    where
-        F: Future,
-    {
-        let waker = unsafe { Waker::from_raw(raw_waker()) };
-        let mut cx = std::task::Context::from_waker(&waker);
-
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-
-        loop {
-            if let Ready(v) = future.as_mut().poll(&mut cx) {
-                return v;
-            }
-        }
-    }
-}
-
-// ===== impl Spawner =====
-
-fn raw_waker() -> RawWaker {
-    RawWaker::new(ptr::null(), waker_vtable())
-}
-
-fn waker_vtable() -> &'static RawWakerVTable {
-    &RawWakerVTable::new(
-        clone_arc_raw,
-        wake_arc_raw,
-        wake_by_ref_arc_raw,
-        drop_arc_raw,
-    )
-}
-
-unsafe fn clone_arc_raw(_: *const ()) -> RawWaker {
-    raw_waker()
-}
-
-unsafe fn wake_arc_raw(_: *const ()) {}
-
-unsafe fn wake_by_ref_arc_raw(_: *const ()) {}
-
-unsafe fn drop_arc_raw(_: *const ()) {}
-
-struct AtomicWaker {}
-
-impl AtomicWaker {
-    /// Create an `AtomicWaker`
-    fn new() -> AtomicWaker {
-        AtomicWaker {}
-    }
-
-    fn register_by_ref(&self, _waker: &Waker) {}
-}
-
-#[allow(dead_code)]
-struct Tx<T> {
-    inner: Arc<Chan<T>>,
-}
-
-struct Rx<T> {
-    inner: Arc<Chan<T>>,
-}
-
-#[allow(dead_code)]
-struct Chan<T> {
-    tx: PhantomData<T>,
-    semaphore: Sema,
-    rx_waker: AtomicWaker,
-    rx_closed: bool,
-}
-
-fn channel<T>() -> (Tx<T>, Rx<T>) {
-    let chan = Arc::new(Chan {
-        tx: PhantomData,
-        semaphore: Sema(AtomicUsize::new(0)),
-        rx_waker: AtomicWaker::new(),
-        rx_closed: false,
-    });
-
-    (
-        Tx {
-            inner: chan.clone(),
-        },
-        Rx { inner: chan },
-    )
-}
-
-// ===== impl Rx =====
-
-impl<T> Rx<T> {
-    /// Receive the next value
-    fn recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<T>> {
-        self.inner.rx_waker.register_by_ref(cx.waker());
-
-        if self.inner.rx_closed && self.inner.semaphore.is_idle() {
-            Ready(None)
-        } else {
-            Pending
-        }
-    }
-}
-
-struct Sema(AtomicUsize);
-
-impl Sema {
-    fn is_idle(&self) -> bool {
-        false
-    }
-}
-
-pub struct UnboundedReceiver<T> {
-    chan: Rx<T>,
-}
-
-pub fn unbounded_channel<T>() -> UnboundedReceiver<T> {
-    let (tx, rx) = channel();
-
-    drop(tx);
-    let rx = UnboundedReceiver { chan: rx };
-
-    rx
-}
-
-impl<T> UnboundedReceiver<T> {
-    pub async fn recv(&mut self) -> Option<T> {
-        poll_fn(|cx| self.chan.recv(cx)).await
-    }
-}
index f73c787346d8cfddc97a77a6a4d0533e97589095..30e74c5ec950c6044205afe52d09947b2f0ca66e 100644 (file)
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |     let x = Box::new(0);
    |         - captured outer variable
 LL |     Box::new(|| x)
-   |                 ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |              ---^
+   |              |  |
+   |              |  move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |              captured by this `Fn` closure
 
 error: aborting due to previous error
 
index 628f206e0a89616cf7629b0ce1f6d5269c124820..05489cf18e7fc9a5b2ebc352536a4b1d7a46f8ea 100644 (file)
@@ -1,15 +1,18 @@
 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;
-   |         --- captured outer variable
-LL |     let _g = to_fn_mut(|| {
-LL |         let _h = to_fn_once(move || -> isize { *bar });
-   |                             ^^^^^^^^^^^^^^^^   ----
-   |                             |                  |
-   |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
-   |                             |                  move occurs due to use in closure
-   |                             move out of `bar` occurs here
+LL |       let bar: Box<_> = box 3;
+   |           --- captured outer variable
+LL |       let _g = to_fn_mut(|| {
+   |  ________________________-
+LL | |         let _h = to_fn_once(move || -> isize { *bar });
+   | |                             ^^^^^^^^^^^^^^^^   ----
+   | |                             |                  |
+   | |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+   | |                             |                  move occurs due to use in closure
+   | |                             move out of `bar` occurs here
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-87456-point-to-closure.rs b/src/test/ui/borrowck/issue-87456-point-to-closure.rs
new file mode 100644 (file)
index 0000000..9fc12ba
--- /dev/null
@@ -0,0 +1,14 @@
+// Regression test for #87456.
+
+fn take_mut(_val: impl FnMut()) {}
+
+fn main() {
+    let val = String::new();
+    //~^ NOTE: captured outer variable
+    take_mut(|| {
+    //~^ NOTE: captured by this `FnMut` closure
+        let _foo: String = val;
+        //~^ ERROR: cannot move out of `val`, a captured variable in an `FnMut` closure [E0507]
+        //~| NOTE: move occurs because
+    })
+}
diff --git a/src/test/ui/borrowck/issue-87456-point-to-closure.stderr b/src/test/ui/borrowck/issue-87456-point-to-closure.stderr
new file mode 100644 (file)
index 0000000..fd38ad7
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
+  --> $DIR/issue-87456-point-to-closure.rs:10:28
+   |
+LL |       let val = String::new();
+   |           --- captured outer variable
+LL |
+LL |       take_mut(|| {
+   |  ______________-
+LL | |
+LL | |         let _foo: String = val;
+   | |                            ^^^
+   | |                            |
+   | |                            move occurs because `val` has type `String`, which does not implement the `Copy` trait
+   | |                            help: consider borrowing here: `&val`
+LL | |
+LL | |
+LL | |     })
+   | |_____- captured by this `FnMut` closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
index dbba33f018397738934faaccf342827c060fc37f..1663ce81d6cf446b5819502eb7b14b8f8c108884 100644 (file)
@@ -1,11 +1,15 @@
 error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9
    |
-LL |     let y = vec![format!("World")];
-   |         - captured outer variable
-LL |     call(|| {
-LL |         y.into_iter();
-   |         ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+LL |       let y = vec![format!("World")];
+   |           - captured outer variable
+LL |       call(|| {
+   |  __________-
+LL | |         y.into_iter();
+   | |         ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+LL | |
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error: aborting due to previous error
 
index 5e3b43a47eeeef69952049d75d122a9489cb600c..2f1dec9d2090c69f231e82a8cc6d9decf653f049 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
   --> $DIR/into-boxed-slice-fail.rs:7:35
    |
 LL |     let _ = Box::into_boxed_slice(boxed_slice);
-   |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `[u8]`
 note: required by `Box::<T, A>::into_boxed_slice`
@@ -24,7 +26,9 @@ error[E0277]: the size for values of type `dyn Debug` cannot be known at compila
   --> $DIR/into-boxed-slice-fail.rs:11:35
    |
 LL |     let _ = Box::into_boxed_slice(boxed_trait);
-   |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             --------------------- ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `dyn Debug`
 note: required by `Box::<T, A>::into_boxed_slice`
diff --git a/src/test/ui/bug-7183-generics.rs b/src/test/ui/bug-7183-generics.rs
deleted file mode 100644 (file)
index f53a173..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// run-pass
-
-trait Speak : Sized {
-    fn say(&self, s:&str) -> String;
-    fn hi(&self) -> String { hello(self) }
-}
-
-fn hello<S:Speak>(s:&S) -> String{
-    s.say("hello")
-}
-
-impl Speak for isize {
-    fn say(&self, s:&str) -> String {
-        format!("{}: {}", s, *self)
-    }
-}
-
-impl<T: Speak> Speak for Option<T> {
-    fn say(&self, s:&str) -> String {
-        match *self {
-            None => format!("{} - none", s),
-            Some(ref x) => { format!("something!{}", x.say(s)) }
-        }
-    }
-}
-
-
-pub fn main() {
-    assert_eq!(3.hi(), "hello: 3".to_string());
-    assert_eq!(Some(Some(3)).hi(),
-               "something!something!hello: 3".to_string());
-    assert_eq!(None::<isize>.hi(), "hello - none".to_string());
-
-    assert_eq!(Some(None::<isize>).hi(), "something!hello - none".to_string());
-    assert_eq!(Some(3).hi(), "something!hello: 3".to_string());
-}
index a4a480ac64d7c213389d0289bb61b002be593dab..14d43c1474c575b92a3ed7ffd9655e6cca54a5a9 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `{float}: Bar` is not satisfied
   --> $DIR/type_inference.rs:27:14
    |
 LL |     only_bar(x);
-   |              ^ the trait `Bar` is not implemented for `{float}`
+   |     -------- ^ the trait `Bar` is not implemented for `{float}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <i32 as Bar>
index 6c77d0809673c4426c406dfb47e4338fdbe7c9ef..d4f230780436ea5c80e632223774bfb2dcbc5c94 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
   --> $DIR/closure-expected.rs:3:23
    |
 LL |     let y = x.or_else(4);
-   |                       ^ expected an `FnOnce<()>` closure, found `{integer}`
+   |               ------- ^ expected an `FnOnce<()>` closure, found `{integer}`
+   |               |
+   |               required by a bound introduced by this call
    |
    = help: the trait `FnOnce<()>` is not implemented for `{integer}`
    = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }`
index bfea4979decaefe31646bb1a044f6c6bd758ce00..1a40326d986c4124e4a765519ebc276e6d83c193 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `F` cannot be shared between threads safely
   --> $DIR/closure-bounds-subtype.rs:13:22
    |
 LL |     take_const_owned(f);
-   |                      ^ `F` cannot be shared between threads safely
+   |     ---------------- ^ `F` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `take_const_owned`
   --> $DIR/closure-bounds-subtype.rs:4:50
index ab035d03b056d0d9dbaaf74b2aa88328e42d3e21..4a47e0549155f9508223981beefcbd89c32958f2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `FnOnce<(&str,)>` closure, found `unsafe extern "rust-i
   --> $DIR/coerce-unsafe-to-closure.rs:2:44
    |
 LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
-   |                                            ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+   |                                        --- ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+   |                                        |
+   |                                        required by a bound introduced by this call
    |
    = help: the trait `FnOnce<(&str,)>` is not implemented for `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
 
diff --git a/src/test/ui/closures/issue-78720.rs b/src/test/ui/closures/issue-78720.rs
new file mode 100644 (file)
index 0000000..4cdb9f4
--- /dev/null
@@ -0,0 +1,19 @@
+fn server() -> impl {
+//~^ ERROR at least one trait must be specified
+    ().map2(|| "")
+}
+
+trait FilterBase2 {
+    fn map2<F>(self, f: F) -> Map2<F> {}
+    //~^ ERROR mismatched types
+    //~^^ ERROR the size for values of type `Self` cannot be known at compilation time
+}
+
+struct Map2<Segment2> {
+    _func: F,
+    //~^ ERROR cannot find type `F` in this scope
+}
+
+impl<F> FilterBase2 for F {}
+
+fn main() {}
diff --git a/src/test/ui/closures/issue-78720.stderr b/src/test/ui/closures/issue-78720.stderr
new file mode 100644 (file)
index 0000000..3dd1387
--- /dev/null
@@ -0,0 +1,55 @@
+error: at least one trait must be specified
+  --> $DIR/issue-78720.rs:1:16
+   |
+LL | fn server() -> impl {
+   |                ^^^^
+
+error[E0412]: cannot find type `F` in this scope
+  --> $DIR/issue-78720.rs:13:12
+   |
+LL |     _func: F,
+   |            ^
+   |
+  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL | pub trait Fn<Args>: FnMut<Args> {
+   | ------------------------------- similarly named trait `Fn` defined here
+   |
+help: a trait with a similar name exists
+   |
+LL |     _func: Fn,
+   |            ~~
+help: you might be missing a type parameter
+   |
+LL | struct Map2<Segment2, F> {
+   |                     +++
+
+error[E0308]: mismatched types
+  --> $DIR/issue-78720.rs:7:39
+   |
+LL |     fn map2<F>(self, f: F) -> Map2<F> {}
+   |                                       ^^ expected struct `Map2`, found `()`
+   |
+   = note: expected struct `Map2<F>`
+           found unit type `()`
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/issue-78720.rs:7:16
+   |
+LL |     fn map2<F>(self, f: F) -> Map2<F> {}
+   |                ^^^^ doesn't have a size known at compile-time
+   |
+   = help: unsized fn params are gated as an unstable feature
+help: consider further restricting `Self`
+   |
+LL |     fn map2<F>(self, f: F) -> Map2<F> where Self: Sized {}
+   |                                       +++++++++++++++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     fn map2<F>(&self, f: F) -> Map2<F> {}
+   |                +
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0412.
+For more information about an error, try `rustc --explain E0277`.
index a2b779e29540b8f4353604b7d044a4426f13057e..e9090c1b6bcfb38f80ddf8628b5c388a679e72af 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |                        ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
    |
-   = help: consider moving `eq` to another trait
 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/coherence-impl-trait-for-trait-object-safe.rs:6:43
    |
@@ -12,6 +11,7 @@ LL | trait NotObjectSafe { fn eq(&self, other: Self); }
    |       -------------                       ^^^^ ...because method `eq` references the `Self` type in this parameter
    |       |
    |       this trait cannot be made into an object...
+   = help: consider moving `eq` to another trait
 
 error: aborting due to previous error
 
index cf842b1908532479e514ac44cc8b055127bd451e..2e2dac288a1da9cd6131b10cd52b36185b4f264f 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied
   --> $DIR/coherence-unsafe-trait-object-impl.rs:15:13
    |
 LL |     takes_t(t);
-   |             ^ the trait `Trait` is not implemented for `&dyn Trait`
+   |     ------- ^ the trait `Trait` is not implemented for `&dyn Trait`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `takes_t`
   --> $DIR/coherence-unsafe-trait-object-impl.rs:10:15
index 319e6c2c032a0e067bf9fd2009cfe3416fbc63f9..4e1d71f154558857424588c3d100d5591912d63c 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object
 LL | fn use_dyn(v: &dyn Foo) {
    |                ^^^^^^^ `Foo` cannot be made into an object
    |
-   = help: consider moving `test` to another trait
 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/object-safety-err-ret.rs:8:23
    |
@@ -12,6 +11,7 @@ LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn test(&self) -> [u8; bar::<Self>()];
    |                       ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
+   = help: consider moving `test` to another trait
 
 error: aborting due to previous error
 
index 7cdfc9dfcdf5a2404ff2b095e37a9f1ed8acb9e1..c63857b2314e9422f5fe31f8f78409df45b212a2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&str: X` is not satisfied
   --> $DIR/issue-86530.rs:16:7
    |
 LL |     z(" ");
-   |       ^^^ the trait `X` is not implemented for `&str`
+   |     - ^^^ the trait `X` is not implemented for `&str`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `z`
   --> $DIR/issue-86530.rs:10:8
diff --git a/src/test/ui/const-generics/issues/issue-87493.rs b/src/test/ui/const-generics/issues/issue-87493.rs
new file mode 100644 (file)
index 0000000..d8599ab
--- /dev/null
@@ -0,0 +1,14 @@
+pub trait MyTrait {
+    type Assoc;
+}
+
+pub fn foo<S, T>(_s: S, _t: T)
+where
+    S: MyTrait,
+    T: MyTrait<Assoc == S::Assoc>,
+    //~^ ERROR: expected one of `,` or `>`, found `==`
+    //~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-87493.stderr b/src/test/ui/const-generics/issues/issue-87493.stderr
new file mode 100644 (file)
index 0000000..8f92eea
--- /dev/null
@@ -0,0 +1,28 @@
+error: expected one of `,` or `>`, found `==`
+  --> $DIR/issue-87493.rs:8:22
+   |
+LL |     T: MyTrait<Assoc == S::Assoc>,
+   |                      ^^ expected one of `,` or `>`
+   |
+help: if you meant to use an associated type binding, replace `==` with `=`
+   |
+LL |     T: MyTrait<Assoc = S::Assoc>,
+   |                      ~
+
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/issue-87493.rs:8:8
+   |
+LL |     T: MyTrait<Assoc == S::Assoc>,
+   |        ^^^^^^^------------------- help: remove these generics
+   |        |
+   |        expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/issue-87493.rs:1:11
+   |
+LL | pub trait MyTrait {
+   |           ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
index e4455d86a1440b7f183c7d96582f5557bcd6d5f2..100faded079d52ce37753bcc108dabb59231e91e 100644 (file)
 
 const X: () = std::unimplemented!();
 //~^ ERROR evaluation of constant value failed
-//
+
 const W: () = std::panic!(MSG);
 //~^ ERROR evaluation of constant value failed
 
+const W2: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
 const Z_CORE: () = core::panic!("cheese");
 //~^ ERROR evaluation of constant value failed
 
@@ -33,3 +36,6 @@
 
 const W_CORE: () = core::panic!(MSG);
 //~^ ERROR evaluation of constant value failed
+
+const W2_CORE: () = core::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
index c0c749ede56126084186ec71a2b79d34283794b8..e98e4a506c0d69cc7c42b39c90167a505c47c60c 100644 (file)
@@ -39,45 +39,61 @@ LL | const W: () = std::panic!(MSG);
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:22:20
+  --> $DIR/const_panic.rs:22:16
+   |
+LL | const W2: () = std::panic!("{}", MSG);
+   |                ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:22:16
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic.rs:25:20
    |
 LL | const Z_CORE: () = core::panic!("cheese");
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:25:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:25:21
+  --> $DIR/const_panic.rs:28:21
    |
 LL | const Z2_CORE: () = core::panic!();
-   |                     ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21
+   |                     ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:28:21
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:28:20
+  --> $DIR/const_panic.rs:31:20
    |
 LL | const Y_CORE: () = core::unreachable!();
-   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20
+   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:31:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:31:20
+  --> $DIR/const_panic.rs:34:20
    |
 LL | const X_CORE: () = core::unimplemented!();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:34:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:34:20
+  --> $DIR/const_panic.rs:37:20
    |
 LL | const W_CORE: () = core::panic!(MSG);
-   |                    ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20
+   |                    ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:37:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic.rs:40:21
+   |
+LL | const W2_CORE: () = core::panic!("{}", MSG);
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:40:21
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
index daef34cd6a3062602ebd1a0d9e332a5d0f0408dc..9b8652a776e61ca31f41a6cbab4843036de8f1d7 100644 (file)
@@ -2,6 +2,8 @@
 #![feature(const_panic)]
 #![crate_type = "lib"]
 
+const MSG: &str = "hello";
+
 const A: () = std::panic!("blÃ¥haj");
 //~^ ERROR evaluation of constant value failed
 
 const D: () = std::unimplemented!();
 //~^ ERROR evaluation of constant value failed
 
-const E: () = core::panic!("shark");
+const E: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
+const A_CORE: () = core::panic!("shark");
+//~^ ERROR evaluation of constant value failed
+
+const B_CORE: () = core::panic!();
 //~^ ERROR evaluation of constant value failed
 
-const F: () = core::panic!();
+const C_CORE: () = core::unreachable!();
 //~^ ERROR evaluation of constant value failed
 
-const G: () = core::unreachable!();
+const D_CORE: () = core::unimplemented!();
 //~^ ERROR evaluation of constant value failed
 
-const H: () = core::unimplemented!();
+const E_CORE: () = core::panic!("{}", MSG);
 //~^ ERROR evaluation of constant value failed
index c1bdab3693d11babcf1bb9f60b9371ed6546227b..9eb241ae8e59db6a620d785e56ffa01395bdb6f4 100644 (file)
@@ -1,67 +1,83 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:5:15
+  --> $DIR/const_panic_2021.rs:7:15
    |
 LL | const A: () = std::panic!("blÃ¥haj");
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blÃ¥haj', $DIR/const_panic_2021.rs:5:15
+   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blÃ¥haj', $DIR/const_panic_2021.rs:7:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:8:15
+  --> $DIR/const_panic_2021.rs:10:15
    |
 LL | const B: () = std::panic!();
-   |               ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:8:15
+   |               ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:10:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:11:15
+  --> $DIR/const_panic_2021.rs:13:15
    |
 LL | const C: () = std::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:11:15
+   |               ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:13:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:14:15
+  --> $DIR/const_panic_2021.rs:16:15
    |
 LL | const D: () = std::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:14:15
+   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:16:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:17:15
+  --> $DIR/const_panic_2021.rs:19:15
    |
-LL | const E: () = core::panic!("shark");
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:17:15
+LL | const E: () = std::panic!("{}", MSG);
+   |               ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:19:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:20:15
+  --> $DIR/const_panic_2021.rs:22:20
    |
-LL | const F: () = core::panic!();
-   |               ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:20:15
+LL | const A_CORE: () = core::panic!("shark");
+   |                    ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:22:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:23:15
+  --> $DIR/const_panic_2021.rs:25:20
    |
-LL | const G: () = core::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:23:15
+LL | const B_CORE: () = core::panic!();
+   |                    ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:25:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic_2021.rs:28:20
+   |
+LL | const C_CORE: () = core::unreachable!();
+   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:28:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:26:15
+  --> $DIR/const_panic_2021.rs:31:20
    |
-LL | const H: () = core::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:26:15
+LL | const D_CORE: () = core::unimplemented!();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:31:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 8 previous errors
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic_2021.rs:34:20
+   |
+LL | const E_CORE: () = core::panic!("{}", MSG);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:34:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/issue-23833.rs b/src/test/ui/consts/issue-23833.rs
new file mode 100644 (file)
index 0000000..d4128fa
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(unused_imports)]
+use std::fmt;
+
+const A_I8_T
+    : [u32; (i8::MAX as i8 - 1i8) as usize]
+    = [0; (i8::MAX as usize) - 1];
+
+fn main() {
+    foo(&A_I8_T[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/consts/issue-34784.rs b/src/test/ui/consts/issue-34784.rs
new file mode 100644 (file)
index 0000000..98d9434
--- /dev/null
@@ -0,0 +1,21 @@
+// run-pass
+
+#![warn(pointer_structural_match)]
+#![allow(dead_code)]
+const C: *const u8 = &0;
+
+fn foo(x: *const u8) {
+    match x {
+        C => {}
+        _ => {}
+    }
+}
+
+const D: *const [u8; 4] = b"abcd";
+
+fn main() {
+    match D {
+        D => {}
+        _ => {}
+    }
+}
index fcbf39d38690b5861ddd04d8d04b3eb9a35d7905..d1c2a04d6a61b395f67a759b81421dd4e7d9ac58 100644 (file)
@@ -214,6 +214,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
+LL |
+LL |     const fn foo(&self) {}
+   |     ------------------- function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
@@ -223,6 +226,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
+LL |
+LL |     const fn foo2(&self) {}
+   |     -------------------- function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
@@ -232,6 +238,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
+LL |
+LL |     const fn foo3(&self) {}
+   |     -------------------- function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
@@ -292,7 +301,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
   --> $DIR/min_const_fn.rs:139:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
@@ -301,7 +312,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
   --> $DIR/min_const_fn.rs:139:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
@@ -310,7 +323,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
   --> $DIR/min_const_fn.rs:139:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
index ce844a2f0716425574d4188d2ee02ed39833055c..2cad8a862be4cba54f578a270339ac0aa02d50bb 100644 (file)
@@ -1,6 +1,8 @@
 error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
   --> $DIR/min_const_fn_dyn.rs:9:5
    |
+LL | const fn no_inner_dyn_trait2(x: Hide) {
+   | ------------------------------------- function declared as const here
 LL |     x.0.field;
    |     ^^^^^^^^^
    |
@@ -11,7 +13,9 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
   --> $DIR/min_const_fn_dyn.rs:12:66
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
-   |                                                                  ^^
+   | -----------------------------------------                        ^^
+   | |
+   | function declared as const here
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
index ecdbbff4d97c3deec79819b0e95fb7f2c2513de1..2538b5533a6d69f57ee3218bdad585c269468994 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `C: Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:31:13
    |
 LL |     is_copy(B { a: 1, b: C });
-   |             ^^^^^^^^^^^^^^^^
-   |             |
-   |             expected an implementor of trait `Copy`
-   |             help: consider borrowing here: `&B { a: 1, b: C }`
+   |     ------- ^^^^^^^^^^^^^^^^
+   |     |       |
+   |     |       expected an implementor of trait `Copy`
+   |     |       help: consider borrowing here: `&B { a: 1, b: C }`
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Copy` for `B<C>`
   --> $DIR/deriving-copyclone.rs:9:10
@@ -23,10 +24,11 @@ error[E0277]: the trait bound `C: Clone` is not satisfied
   --> $DIR/deriving-copyclone.rs:32:14
    |
 LL |     is_clone(B { a: 1, b: C });
-   |              ^^^^^^^^^^^^^^^^
-   |              |
-   |              expected an implementor of trait `Clone`
-   |              help: consider borrowing here: `&B { a: 1, b: C }`
+   |     -------- ^^^^^^^^^^^^^^^^
+   |     |        |
+   |     |        expected an implementor of trait `Clone`
+   |     |        help: consider borrowing here: `&B { a: 1, b: C }`
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Clone` for `B<C>`
   --> $DIR/deriving-copyclone.rs:9:16
@@ -44,10 +46,11 @@ error[E0277]: the trait bound `D: Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:35:13
    |
 LL |     is_copy(B { a: 1, b: D });
-   |             ^^^^^^^^^^^^^^^^
-   |             |
-   |             expected an implementor of trait `Copy`
-   |             help: consider borrowing here: `&B { a: 1, b: D }`
+   |     ------- ^^^^^^^^^^^^^^^^
+   |     |       |
+   |     |       expected an implementor of trait `Copy`
+   |     |       help: consider borrowing here: `&B { a: 1, b: D }`
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Copy` for `B<D>`
   --> $DIR/deriving-copyclone.rs:9:10
diff --git a/src/test/ui/deriving/issue-3935.rs b/src/test/ui/deriving/issue-3935.rs
new file mode 100644 (file)
index 0000000..e98d68e
--- /dev/null
@@ -0,0 +1,13 @@
+// run-pass
+
+#[derive(PartialEq)]
+struct Bike {
+    name: String,
+}
+
+pub fn main() {
+    let town_bike = Bike { name: "schwinn".to_string() };
+    let my_bike = Bike { name: "surly".to_string() };
+
+    assert!(town_bike != my_bike);
+}
index fcb4ea1d592b589d81bbeb0a174890e993335348..c7458916c536492e9b7da88fa3de4b435fefe4fd 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:24:21
    |
 LL |     Foo::<i32>::bar(&1i8);
-   |                     ^^^^ the trait `Foo<i32>` is not implemented for `i8`
+   |     --------------- ^^^^ the trait `Foo<i32>` is not implemented for `i8`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <i8 as Foo<bool>>
@@ -20,7 +22,9 @@ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:25:21
    |
 LL |     Foo::<i32>::bar(&1u8);
-   |                     ^^^^ the trait `Foo<i32>` is not implemented for `u8`
+   |     --------------- ^^^^ the trait `Foo<i32>` is not implemented for `u8`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <u8 as Foo<bool>>
@@ -37,7 +41,9 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:26:21
    |
 LL |     Foo::<i32>::bar(&true);
-   |                     ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
+   |     --------------- ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <bool as Foo<bool>>
diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs
deleted file mode 100644 (file)
index aa6a973..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Test that enabling an unstable feature disables warnings
-
-// aux-build:stability-cfg2.rs
-
-#![feature(unstable_test_feature)]
-#![deny(non_snake_case)] // To trigger a hard error
-
-// Shouldn't generate a warning about unstable features
-extern crate stability_cfg2;
-
-pub fn BOGUS() { } //~ ERROR
-
-pub fn main() { }
diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr
deleted file mode 100644 (file)
index bb4e928..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error: function `BOGUS` should have a snake case name
-  --> $DIR/enable-unstable-lib-feature.rs:11:8
-   |
-LL | pub fn BOGUS() { }
-   |        ^^^^^ help: convert the identifier to snake case: `bogus`
-   |
-note: the lint level is defined here
-  --> $DIR/enable-unstable-lib-feature.rs:6:9
-   |
-LL | #![deny(non_snake_case)] // To trigger a hard error
-   |         ^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
index cead9776e4abb3a4a4d96319cbc747a6d84df428..3773d6f5234b0ca88cc8aafef6e7598d02733606 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object
 LL | fn call_foo(x: Box<dyn Trait>) {
    |                    ^^^^^^^^^ `Trait` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/E0038.rs:2:22
    |
@@ -12,6 +11,7 @@ LL | trait Trait {
    |       ----- this trait cannot be made into an object...
 LL |     fn foo(&self) -> Self;
    |                      ^^^^ ...because method `foo` references the `Self` type in its return type
+   = help: consider moving `foo` to another trait
 
 error: aborting due to previous error
 
index c82665aa580ba326f44bd1a35ed97b6f4cc806e0..2b4784d7eccbd5ed8258814c2c53d72d327ff1f6 100644 (file)
@@ -16,7 +16,9 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/E0277.rs:15:15
    |
 LL |     some_func(5i32);
-   |               ^^^^ the trait `Foo` is not implemented for `i32`
+   |     --------- ^^^^ the trait `Foo` is not implemented for `i32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `some_func`
   --> $DIR/E0277.rs:7:17
index 8c6025e708e8ae395d534198c03c1fac1483b925..637eb27db01e675a5e847493bba30295dacacfef 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/error-should-say-copy-not-pod.rs:6:17
    |
 LL |     check_bound("nocopy".to_string());
-   |                 ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |     ----------- ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check_bound`
   --> $DIR/error-should-say-copy-not-pod.rs:3:18
diff --git a/src/test/ui/expr-empty-ret.rs b/src/test/ui/expr-empty-ret.rs
deleted file mode 100644 (file)
index ce8ffaf..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-// Issue #521
-
-// pretty-expanded FIXME #23616
-
-fn f() {
-    let _x = match true {
-        true => { 10 }
-        false => { return }
-    };
-}
-
-pub fn main() { }
index 99df0632b4c3383bdf3a100e79ae754b4b2c0063..14d28b59648c1abfe943890319391d7f82ce3091 100644 (file)
@@ -5,10 +5,19 @@ LL |         Some(x * 2)
    |              ^ not found in this scope
 
 error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
-  --> $DIR/ruby_style_closure.rs:10:22
+  --> $DIR/ruby_style_closure.rs:10:31
    |
-LL |     let p = Some(45).and_then({
-   |                      ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
+LL |       let p = Some(45).and_then({
+   |  ______________________--------_^
+   | |                      |
+   | |                      required by a bound introduced by this call
+LL | |
+LL | |         |x| println!("doubling {}", x);
+LL | |         Some(x * 2)
+   | |         -----------
+LL | |
+LL | |     });
+   | |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
    |
    = help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
 
index 74981ebb76c932952b92f7c31cb87c89ca5311fb..c6f0d5df9b53b3ba44a5f93e32ed5e5232a9da74 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<()>` closure, found `extern "C" fn() {f}`
   --> $DIR/extern-wrong-value-type.rs:9:11
    |
 LL |     is_fn(f);
-   |           ^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
+   |     ----- ^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Fn<()>` is not implemented for `extern "C" fn() {f}`
    = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }`
index a3bd65e518e4ced281311b20597432e9f9daadbe..72cb4cc843cc42b746e5f30127a4d0913256ce3b 100644 (file)
@@ -40,7 +40,6 @@ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
 LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
    |                                       ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/feature-gate-object_safe_for_dispatch.rs:11:8
    |
@@ -48,6 +47,7 @@ LL | trait NonObjectSafe3 {
    |       -------------- this trait cannot be made into an object...
 LL |     fn foo<T>(&self);
    |        ^^^ ...because method `foo` has generic type parameters
+   = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35
@@ -55,7 +55,6 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
 LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/feature-gate-object_safe_for_dispatch.rs:15:22
    |
@@ -63,6 +62,7 @@ LL | trait NonObjectSafe4 {
    |       -------------- this trait cannot be made into an object...
 LL |     fn foo(&self, s: &Self);
    |                      ^^^^^ ...because method `foo` references the `Self` type in this parameter
+   = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16
diff --git a/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs b/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs
deleted file mode 100644 (file)
index bd815db..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-struct Foo {
-    foo: u8,
-    _: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
-    //~^ ERROR unnamed fields are not yet fully implemented [E0658]
-    //~| ERROR anonymous unions are unimplemented
-        bar: u8,
-        baz: u16
-    }
-}
-
-union Bar {
-    foobar: u8,
-    _: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
-    //~^ ERROR unnamed fields are not yet fully implemented [E0658]
-    //~| ERROR anonymous structs are unimplemented
-    //~| ERROR unions may not contain fields that need dropping [E0740]
-        foobaz: u8,
-        barbaz: u16
-    }
-}
-
-struct S;
-struct Baz {
-    _: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
-}
-
-fn main(){}
diff --git a/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr b/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr
deleted file mode 100644 (file)
index 4f3ab85..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-error[E0658]: unnamed fields are not yet fully implemented
-  --> $DIR/feature-gate-unnamed_fields.rs:3:5
-   |
-LL |     _: union {
-   |     ^
-   |
-   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
-   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
-  --> $DIR/feature-gate-unnamed_fields.rs:3:8
-   |
-LL |       _: union {
-   |  ________^
-LL | |
-LL | |
-LL | |         bar: u8,
-LL | |         baz: u16
-LL | |     }
-   | |_____^
-   |
-   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
-   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
-  --> $DIR/feature-gate-unnamed_fields.rs:13:5
-   |
-LL |     _: struct {
-   |     ^
-   |
-   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
-   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
-  --> $DIR/feature-gate-unnamed_fields.rs:13:8
-   |
-LL |       _: struct {
-   |  ________^
-LL | |
-LL | |
-LL | |
-LL | |         foobaz: u8,
-LL | |         barbaz: u16
-LL | |     }
-   | |_____^
-   |
-   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
-   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error[E0658]: unnamed fields are not yet fully implemented
-  --> $DIR/feature-gate-unnamed_fields.rs:24:5
-   |
-LL |     _: S
-   |     ^
-   |
-   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
-   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
-
-error: anonymous unions are unimplemented
-  --> $DIR/feature-gate-unnamed_fields.rs:3:8
-   |
-LL |       _: union {
-   |  ________^
-LL | |
-LL | |
-LL | |         bar: u8,
-LL | |         baz: u16
-LL | |     }
-   | |_____^
-
-error: anonymous structs are unimplemented
-  --> $DIR/feature-gate-unnamed_fields.rs:13:8
-   |
-LL |       _: struct {
-   |  ________^
-LL | |
-LL | |
-LL | |
-LL | |         foobaz: u8,
-LL | |         barbaz: u16
-LL | |     }
-   | |_____^
-
-error[E0740]: unions may not contain fields that need dropping
-  --> $DIR/feature-gate-unnamed_fields.rs:13:5
-   |
-LL | /     _: struct {
-LL | |
-LL | |
-LL | |
-LL | |         foobaz: u8,
-LL | |         barbaz: u16
-LL | |     }
-   | |_____^
-   |
-note: `std::mem::ManuallyDrop` can be used to wrap the type
-  --> $DIR/feature-gate-unnamed_fields.rs:13:5
-   |
-LL | /     _: struct {
-LL | |
-LL | |
-LL | |
-LL | |         foobaz: u8,
-LL | |         barbaz: u16
-LL | |     }
-   | |_____^
-
-error: aborting due to 8 previous errors
-
-Some errors have detailed explanations: E0658, E0740.
-For more information about an error, try `rustc --explain E0658`.
index fbb18c8c4909705c058429ac44f851f9bcfd99e5..0f7520ef7f8a95a80644466eedf36a0a5902a143 100644 (file)
@@ -12,10 +12,10 @@ LL | fn foo(x: &dyn Foo) {
    |           +
 
 error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
-  --> $DIR/feature-gate-unsized_fn_params.rs:24:5
+  --> $DIR/feature-gate-unsized_fn_params.rs:24:9
    |
 LL |     foo(*x);
-   |     ^^^ doesn't have a size known at compile-time
+   |         ^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
    = note: all function arguments must have a statically known size
index 57a25b8e48b351c7988ff5943ab9b088296e6344..f9fb3a0ef267dbfbd50bfe9f30ecb29ad43c4848 100644 (file)
@@ -35,7 +35,9 @@ error[E0277]: expected a `Fn<(isize,)>` closure, found `{integer}`
   --> $DIR/fn-trait-formatting.rs:19:14
    |
 LL |     needs_fn(1);
-   |              ^ expected an `Fn<(isize,)>` closure, found `{integer}`
+   |     -------- ^ expected an `Fn<(isize,)>` closure, found `{integer}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Fn<(isize,)>` is not implemented for `{integer}`
 note: required by a bound in `needs_fn`
diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs
new file mode 100644 (file)
index 0000000..ce9159b
--- /dev/null
@@ -0,0 +1,19 @@
+// Regression test for #88653, where a confusing warning about a
+// type mismatch in generator arguments was issued.
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+fn foo(bar: bool) -> impl Generator<(bool,)> {
+//~^ ERROR: type mismatch in generator arguments [E0631]
+//~| NOTE: expected signature of `fn((bool,)) -> _`
+    |bar| {
+    //~^ NOTE: found signature of `fn(bool) -> _`
+        if bar {
+            yield bar;
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr
new file mode 100644 (file)
index 0000000..5bd8ad1
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0631]: type mismatch in generator arguments
+  --> $DIR/issue-88653.rs:8:22
+   |
+LL | fn foo(bar: bool) -> impl Generator<(bool,)> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
+...
+LL |     |bar| {
+   |     ----- found signature of `fn(bool) -> _`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.
index 7ae128d072dd9bca3120fc507baa34978c3f7a6d..4ae745b0ffeacae0b44f51142e7d37db5e1c0246 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6]` cannot b
   --> $DIR/static-not-unpin.rs:14:18
    |
 LL |     assert_unpin(generator);
-   |                  ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6]`
+   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6]`
+   |     |
+   |     required by a bound introduced by this call
    |
    = note: consider using `Box::pin`
 note: required by a bound in `assert_unpin`
index 8651789688eaa75d4f850b00e1a19382a6f23eb3..a55642490f975eda5797eef92446e1f5986b2859 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object
 LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
-   = help: consider moving `A` to another trait
 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/gat-in-trait-path.rs:5:10
    |
@@ -12,6 +11,7 @@ LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     type A<'a> where Self: 'a;
    |          ^ ...because it contains the generic associated type `A`
+   = help: consider moving `A` to another trait
 
 error: aborting due to previous error
 
index b4b89ab047363ce28c2cf43558a2c455b4484b8a..7dd1bdf891eb572599764d9928fbbd4994cabe14 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `X` cannot be made into an object
 LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
    |                       ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
    |
-   = help: consider moving `Y` to another trait
 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/issue-67510-pass.rs:4:10
    |
@@ -12,6 +11,7 @@ LL | trait X {
    |       - this trait cannot be made into an object...
 LL |     type Y<'a>;
    |          ^ ...because it contains the generic associated type `Y`
+   = help: consider moving `Y` to another trait
 
 error: aborting due to previous error
 
index 246454f0612dbb76e22ae60bcde1171b89f31037..0a7eb5dde6009838b44af2b5c6ff9bc75bdb03bb 100644 (file)
@@ -20,7 +20,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object
 LL |     let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
    |
-   = help: consider moving `SubType` to another trait
 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/issue-76535.rs:6:10
    |
@@ -28,6 +27,7 @@ LL | pub trait SuperTrait {
    |           ---------- this trait cannot be made into an object...
 LL |     type SubType<'a>: SubTrait;
    |          ^^^^^^^ ...because it contains the generic associated type `SubType`
+   = help: consider moving `SubType` to another trait
 
 error[E0038]: the trait `SuperTrait` cannot be made into an object
   --> $DIR/issue-76535.rs:36:57
@@ -35,7 +35,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object
 LL |     let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
    |
-   = help: consider moving `SubType` to another trait
 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/issue-76535.rs:6:10
    |
@@ -43,6 +42,7 @@ LL | pub trait SuperTrait {
    |           ---------- this trait cannot be made into an object...
 LL |     type SubType<'a>: SubTrait;
    |          ^^^^^^^ ...because it contains the generic associated type `SubType`
+   = help: consider moving `SubType` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
    = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
 
index b92730839568d47ea5543cf33aefb71a16e59bd0..17dd0ff4a0c94088a5bc09ecf56ed22a5a644bee 100644 (file)
@@ -20,7 +20,6 @@ error[E0038]: the trait `CollectionFamily` cannot be made into an object
 LL |     Box::new(Family) as &dyn CollectionFamily<Member=usize>
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
    |
-   = help: consider moving `Member` to another trait
 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/issue-78671.rs:4:10
    |
@@ -28,6 +27,7 @@ LL | trait CollectionFamily {
    |       ---------------- this trait cannot be made into an object...
 LL |     type Member<T>;
    |          ^^^^^^ ...because it contains the generic associated type `Member`
+   = help: consider moving `Member` to another trait
 
 error: aborting due to 2 previous errors
 
index 8d8ef6bf836854602bd1ca900d411280b70c4c85..b6f856a97e7257fcc8c5a9795e024846ff4159f9 100644 (file)
@@ -20,7 +20,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object
 LL |         as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
    |
-   = help: consider moving `VRefCont` to another trait
 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/issue-79422.rs:20:10
    |
@@ -28,6 +27,7 @@ LL | trait MapLike<K, V> {
    |       ------- this trait cannot be made into an object...
 LL |     type VRefCont<'a>: RefCont<'a, V>;
    |          ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
+   = help: consider moving `VRefCont` to another trait
 
 error[E0038]: the trait `MapLike` cannot be made into an object
   --> $DIR/issue-79422.rs:41:13
@@ -35,7 +35,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object
 LL |     let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
    |
-   = help: consider moving `VRefCont` to another trait
 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/issue-79422.rs:20:10
    |
@@ -43,6 +42,7 @@ LL | trait MapLike<K, V> {
    |       ------- this trait cannot be made into an object...
 LL |     type VRefCont<'a>: RefCont<'a, V>;
    |          ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
+   = help: consider moving `VRefCont` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
    = note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
 
index 6429bb8159e1f9899debc6bce4e7d442e6148a3e..5ab37910207ca8d78abbf0b45e13733af78a8bf5 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object
 LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
    |
-   = help: consider moving `Item` to another trait
 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/trait-objects.rs:4:10
    |
@@ -12,6 +11,7 @@ LL | trait StreamingIterator {
    |       ----------------- this trait cannot be made into an object...
 LL |     type Item<'a> where Self: 'a;
    |          ^^^^ ...because it contains the generic associated type `Item`
+   = help: consider moving `Item` to another trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generics/mid-path-type-params.rs b/src/test/ui/generics/mid-path-type-params.rs
new file mode 100644 (file)
index 0000000..a812820
--- /dev/null
@@ -0,0 +1,37 @@
+// run-pass
+
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+struct S<T> {
+    contents: T,
+}
+
+impl<T> S<T> {
+    fn new<U>(x: T, _: U) -> S<T> {
+        S {
+            contents: x,
+        }
+    }
+}
+
+trait Trait<T> {
+    fn new<U>(x: T, y: U) -> Self;
+}
+
+struct S2 {
+    contents: isize,
+}
+
+impl Trait<isize> for S2 {
+    fn new<U>(x: isize, _: U) -> S2 {
+        S2 {
+            contents: x,
+        }
+    }
+}
+
+pub fn main() {
+    let _ = S::<isize>::new::<f64>(1, 1.0);
+    let _: S2 = Trait::<isize>::new::<f64>(1, 1.0);
+}
diff --git a/src/test/ui/guards.rs b/src/test/ui/guards.rs
deleted file mode 100644 (file)
index 10a4bb6..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// run-pass
-
-#![allow(non_shorthand_field_patterns)]
-
-#[derive(Copy, Clone)]
-struct Pair { x: isize, y: isize }
-
-pub fn main() {
-    let a: isize =
-        match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } };
-    assert_eq!(a, 2);
-
-    let b: isize =
-        match (Pair {x: 10, y: 20}) {
-          x if x.x < 5 && x.y < 5 => { 1 }
-          Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
-          Pair {x: _x, y: _y} => { 3 }
-        };
-    assert_eq!(b, 2);
-}
index 8311c147ee3bdea371bdcee987ea3524697fdaee..b13226fef6e76fe7ada4ad5948fa3f7428d26faa 100644 (file)
@@ -1,11 +1,19 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/issue-62529-1.rs:80:10
    |
-LL |     task(annotate(
-   |          ^^^^^^^^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
-...
-LL |         |value: &mut usize| {
-   |         ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
+LL |       task(annotate(
+   |  _____----_^
+   | |     |
+   | |     required by a bound introduced by this call
+LL | |
+LL | |
+LL | |         Annotate::<RefMutFamily<usize>>::new(),
+LL | |         |value: &mut usize| {
+   | |         ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
+LL | |             *value = 2;
+LL | |         }
+LL | |     ));
+   | |_____^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
    |
 note: required by a bound in `annotate`
   --> $DIR/issue-62529-1.rs:44:8
@@ -20,7 +28,9 @@ error[E0277]: the size for values of type `impl Execute` cannot be known at comp
   --> $DIR/issue-62529-1.rs:80:10
    |
 LL |       task(annotate(
-   |  __________^
+   |  _____----_^
+   | |     |
+   | |     required by a bound introduced by this call
 LL | |
 LL | |
 LL | |         Annotate::<RefMutFamily<usize>>::new(),
@@ -44,7 +54,9 @@ error[E0277]: the trait bound `impl Execute: Execute` is not satisfied
   --> $DIR/issue-62529-1.rs:80:10
    |
 LL |       task(annotate(
-   |  __________^
+   |  _____----_^
+   | |     |
+   | |     required by a bound introduced by this call
 LL | |
 LL | |
 LL | |         Annotate::<RefMutFamily<usize>>::new(),
index d8267712c2b8a9c11b7a47b05419c2292d2f428e..8cda76b9490c2faa02aa7911ff42ab729a8f9e98 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
    |
 LL |     want_bar_for_any_ccx(b);
-   |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `want_bar_for_any_ccx`
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
index a510c05055c1481ae732838cd799181a7b31f21d..88793a1525bfb7ba98d4bb881f27108607c75698 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
    |
 LL |     want_foo_for_any_tcx(f);
-   |                          ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+   |     -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `want_foo_for_any_tcx`
   --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
@@ -20,7 +22,9 @@ error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
    |
 LL |     want_bar_for_any_ccx(b);
-   |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `want_bar_for_any_ccx`
   --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
diff --git a/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.rs b/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.rs
new file mode 100644 (file)
index 0000000..ecfa5c6
--- /dev/null
@@ -0,0 +1,16 @@
+trait Foo {
+    type T;
+    fn foo(&self, t: Self::T);
+//~^ NOTE expected 0 type parameters
+}
+
+impl Foo for u32 {
+    type T = ();
+
+    fn foo(&self, t: impl Clone) {}
+//~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+//~| NOTE found 1 type parameter
+//~| NOTE `impl Trait` introduces an implicit type parameter
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.stderr b/src/test/ui/impl-trait/type-arg-mismatch-due-to-impl-trait.stderr
new file mode 100644 (file)
index 0000000..30322f8
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/type-arg-mismatch-due-to-impl-trait.rs:10:22
+   |
+LL |     fn foo(&self, t: Self::T);
+   |           - expected 0 type parameters
+...
+LL |     fn foo(&self, t: impl Clone) {}
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      found 1 type parameter
+   |                      `impl Trait` introduces an implicit type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/src/test/ui/inference/issue-71309.rs b/src/test/ui/inference/issue-71309.rs
new file mode 100644 (file)
index 0000000..c31107d
--- /dev/null
@@ -0,0 +1,7 @@
+fn foo(x: Result<i32, ()>) -> Result<(), ()> {
+    let y: u32 = x?;
+    //~^ ERROR: `?` operator has incompatible types
+    Ok(())
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/issue-71309.stderr b/src/test/ui/inference/issue-71309.stderr
new file mode 100644 (file)
index 0000000..af8714f
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0308]: `?` operator has incompatible types
+  --> $DIR/issue-71309.rs:2:18
+   |
+LL |     let y: u32 = x?;
+   |                  ^^ expected `u32`, found `i32`
+   |
+   = note: `?` operator cannot convert from `i32` to `u32`
+help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
+   |
+LL |     let y: u32 = x?.try_into().unwrap();
+   |                    ++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issue-72470-llvm-dominate.rs b/src/test/ui/issue-72470-llvm-dominate.rs
deleted file mode 100644 (file)
index 5bb69a0..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// compile-flags: -C opt-level=3
-// aux-build: issue-72470-lib.rs
-// edition:2018
-// build-pass
-
-// Regression test for issue #72470, using the minimization
-// in https://github.com/jonas-schievink/llvm-error
-
-extern crate issue_72470_lib;
-
-use std::future::Future;
-use std::pin::Pin;
-use std::sync::Mutex;
-use std::task::Poll::{Pending, Ready};
-
-#[allow(dead_code)]
-enum Msg {
-    A(Vec<()>),
-    B,
-}
-
-#[allow(dead_code)]
-enum Out {
-    _0(Option<Msg>),
-    Disabled,
-}
-
-#[allow(unused_must_use)]
-fn main() {
-    let mut rx = issue_72470_lib::unbounded_channel::<Msg>();
-    let entity = Mutex::new(());
-    issue_72470_lib::run(async move {
-        {
-            let output = {
-                let mut fut = rx.recv();
-                issue_72470_lib::poll_fn(|cx| {
-                    loop {
-                        let fut = unsafe { Pin::new_unchecked(&mut fut) };
-                        let out = match fut.poll(cx) {
-                            Ready(out) => out,
-                            Pending => {
-                                break;
-                            }
-                        };
-                        #[allow(unused_variables)]
-                        match &out {
-                            Some(_msg) => {}
-                            _ => break,
-                        }
-                        return Ready(Out::_0(out));
-                    }
-                    Ready(Out::_0(None))
-                })
-                .await
-            };
-            match output {
-                Out::_0(Some(_msg)) => {
-                    entity.lock();
-                }
-                Out::_0(None) => unreachable!(),
-                _ => unreachable!(),
-            }
-        }
-        entity.lock();
-    });
-}
index 08f352c11fa12cce2dc6069f9d59749b8e89a87b..7629a5a3be1ea475a59ff154d41fecfb8f7669f6 100644 (file)
@@ -4,5 +4,4 @@
 fn main() {
     (|| Box::new(*(&[0][..])))();
     //~^ ERROR the size for values of type
-    //~| ERROR the size for values of type
 }
index ee1464fd8481105f4f87e2969c2dc80aaccaf7b2..214477f6c60ef4881258e7fa883a53453acb06f9 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compi
   --> $DIR/issue-17651.rs:5:18
    |
 LL |     (|| Box::new(*(&[0][..])))();
-   |                  ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |         -------- ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `[{integer}]`
 note: required by `Box::<T>::new`
@@ -11,16 +13,6 @@ note: required by `Box::<T>::new`
 LL |     pub fn new(x: T) -> Self {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
-  --> $DIR/issue-17651.rs:5:9
-   |
-LL |     (|| Box::new(*(&[0][..])))();
-   |         ^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[{integer}]`
-   = note: all function arguments must have a statically known size
-   = help: unsized fn params are gated as an unstable feature
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
index 2a5416ce85ba65e78140c4a40aaa85dce68c7338..b9e27873636c3302c567ca2d8b9037d59ab4cf5d 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | fn foo(b: &dyn Bar) {
    |            ^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/issue-18959.rs:1:20
    |
@@ -12,6 +11,7 @@ LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
    |                    ^^^ ...because method `foo` has generic type parameters
 LL | pub trait Bar: Foo { }
    |           --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
 
 error: aborting due to previous error
 
index 555d0ff0dc787c71f92fce52d3dea6df749bf055..7b37e1f95dcc654da9b864e543b211b3c480a990 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     let test: &mut dyn Bar = &mut thing;
    |               ^^^^^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/issue-19538.rs:2:8
    |
@@ -13,6 +12,7 @@ LL |     fn foo<T>(&self, val: T);
 ...
 LL | trait Bar: Foo { }
    |       --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:30
@@ -20,7 +20,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     let test: &mut dyn Bar = &mut thing;
    |                              ^^^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/issue-19538.rs:2:8
    |
@@ -29,6 +28,7 @@ LL |     fn foo<T>(&self, val: T);
 ...
 LL | trait Bar: Foo { }
    |       --- this trait cannot be made into an object...
+   = help: consider moving `foo` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
    = note: required by cast to type `&mut dyn Bar`
 
diff --git a/src/test/ui/issues/issue-19883.rs b/src/test/ui/issues/issue-19883.rs
deleted file mode 100644 (file)
index 5cf4220..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-trait From<Src> {
-    type Output;
-
-    fn from(src: Src) -> <Self as From<Src>>::Output;
-}
-
-trait To: Sized {
-    fn to<Dst: From<Self>>(self) ->
-        <Dst as From<Self>>::Dst
-        //~^ ERROR cannot find associated type `Dst` in trait `From`
-    {
-        From::from(self)
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-19883.stderr b/src/test/ui/issues/issue-19883.stderr
deleted file mode 100644 (file)
index bd6a86b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0576]: cannot find associated type `Dst` in trait `From`
-  --> $DIR/issue-19883.rs:9:30
-   |
-LL |     type Output;
-   |     ------------ associated type `Output` defined here
-...
-LL |         <Dst as From<Self>>::Dst
-   |                              ^^^
-   |                              |
-   |                              not found in `From`
-   |                              help: maybe you meant this associated type: `Output`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0576`.
diff --git a/src/test/ui/issues/issue-20692.rs b/src/test/ui/issues/issue-20692.rs
deleted file mode 100644 (file)
index 1cb2d8c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-trait Array: Sized + Copy {}
-
-fn f<T: Array>(x: &T) {
-    let _ = x
-    //~^ ERROR `Array` cannot be made into an object
-    as
-    &dyn Array;
-    //~^ ERROR `Array` cannot be made into an object
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr
deleted file mode 100644 (file)
index 1d7f252..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0038]: the trait `Array` cannot be made into an object
-  --> $DIR/issue-20692.rs:7:5
-   |
-LL |     &dyn Array;
-   |     ^^^^^^^^^^ `Array` 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/issue-20692.rs:1:14
-   |
-LL | trait Array: Sized + Copy {}
-   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
-   |       |      |
-   |       |      ...because it requires `Self: Sized`
-   |       this trait cannot be made into an object...
-
-error[E0038]: the trait `Array` cannot be made into an object
-  --> $DIR/issue-20692.rs:4:13
-   |
-LL |     let _ = x
-   |             ^ `Array` 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/issue-20692.rs:1:14
-   |
-LL | trait Array: Sized + Copy {}
-   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
-   |       |      |
-   |       |      ...because it requires `Self: Sized`
-   |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T`
-   = note: required by cast to type `&dyn Array`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/issues/issue-21363.rs
deleted file mode 100644 (file)
index acc28cb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// check-pass
-// pretty-expanded FIXME #23616
-
-#![no_implicit_prelude]
-
-trait Iterator {
-    type Item;
-    fn dummy(&self) { }
-}
-
-impl<'a, T> Iterator for &'a mut (dyn Iterator<Item=T> + 'a) {
-    type Item = T;
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-23825.rs b/src/test/ui/issues/issue-23825.rs
deleted file mode 100644 (file)
index a9f0095..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-trait Stringify {
-    fn to_string(&self) -> String;
-}
-
-impl Stringify for u32 {
-    fn to_string(&self) -> String { format!("u32: {}", *self) }
-}
-
-impl Stringify for f32 {
-    fn to_string(&self) -> String { format!("f32: {}", *self) }
-}
-
-fn print<T: Stringify>(x: T) -> String {
-    x.to_string()
-}
-
-fn main() {
-    assert_eq!(&print(5), "u32: 5");
-    assert_eq!(&print(5.0), "f32: 5");
-}
diff --git a/src/test/ui/issues/issue-23833.rs b/src/test/ui/issues/issue-23833.rs
deleted file mode 100644 (file)
index d4128fa..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-#![allow(unused_imports)]
-use std::fmt;
-
-const A_I8_T
-    : [u32; (i8::MAX as i8 - 1i8) as usize]
-    = [0; (i8::MAX as usize) - 1];
-
-fn main() {
-    foo(&A_I8_T[..]);
-}
-
-fn foo<T:fmt::Debug>(x: T) {
-    println!("{:?}", x);
-}
index fff9b3c303a637d8071659f4dd7f8a0893b14d9c..9c87ee6104a0d27e25f56b3cd47020ca8ccabee1 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `FnMut<(_, char)>` closure, found `()`
   --> $DIR/issue-23966.rs:2:32
    |
 LL |     "".chars().fold(|_, _| (), ());
-   |                                ^^ expected an `FnMut<(_, char)>` closure, found `()`
+   |                ----            ^^ expected an `FnMut<(_, char)>` closure, found `()`
+   |                |
+   |                required by a bound introduced by this call
    |
    = help: the trait `FnMut<(_, char)>` is not implemented for `()`
 
index ece99596e58f406844ac5846434548c804d09f0d..159cc484c5d4f35c196f66a874c4592d91a31ce1 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `(): InOut<_>` is not satisfied
   --> $DIR/issue-25076.rs:10:20
    |
 LL |     do_fold(bot(), ());
-   |                    ^^ the trait `InOut<_>` is not implemented for `()`
+   |     -------        ^^ the trait `InOut<_>` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `do_fold`
   --> $DIR/issue-25076.rs:5:18
index 70caeb0ea39092578f8c7d32a234dfd8504f645f..6a74f4ed489a16828f1224aa340f28d24610bd0c 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:2:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |                            ^^^^^^^ `()` is not an iterator
+   |             -------------- ^^^^^^^ `()` is not an iterator
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Iterator` is not implemented for `()`
 note: required by `std::iter::Iterator::next`
@@ -29,7 +31,9 @@ error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:9:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |                            ^^^^^^^ `()` is not an iterator
+   |             -------------- ^^^^^^^ `()` is not an iterator
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Iterator` is not implemented for `()`
 note: required by `std::iter::Iterator::next`
@@ -50,7 +54,9 @@ error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:18:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |                            ^^^^^^^ `()` is not an iterator
+   |             -------------- ^^^^^^^ `()` is not an iterator
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Iterator` is not implemented for `()`
 note: required by `std::iter::Iterator::next`
@@ -63,7 +69,9 @@ error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:22:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |                            ^^^^^^^ `()` is not an iterator
+   |             -------------- ^^^^^^^ `()` is not an iterator
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Iterator` is not implemented for `()`
 note: required by `std::iter::Iterator::next`
index 79f5db650d9dcb76e89b0917aeae621e0e6a45bf..71bbdf5dec7696600f3a02ee2544624d0c097244 100644 (file)
@@ -1,8 +1,8 @@
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/issue-30355.rs:5:6
+  --> $DIR/issue-30355.rs:5:8
    |
 LL |     &X(*Y)
-   |      ^ doesn't have a size known at compile-time
+   |        ^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
    = note: all function arguments must have a statically known size
diff --git a/src/test/ui/issues/issue-33498.rs b/src/test/ui/issues/issue-33498.rs
deleted file mode 100644 (file)
index 9c8a97e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-#![allow(unused_variables)]
-pub fn main() {
-    let x = (0, 2);
-
-    match x {
-        (0, ref y) => {}
-        (y, 0) => {}
-        _ => (),
-    }
-}
diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/issues/issue-34194.rs
deleted file mode 100644 (file)
index 6dce556..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// build-pass
-#![allow(dead_code)]
-
-struct A {
-    a: &'static (),
-}
-
-static B: &'static A = &A { a: &() };
-static C: &'static A = &B;
-
-fn main() {}
index b1071934bb2f3cea0aeb98e1833e4412da85f23e..c70cd8b5077a924fa9ef52a5f988d7a31ff0b1ef 100644 (file)
@@ -6,5 +6,5 @@ enum Test {
 
 fn main() {
     Test::Drill(field: 42);
-    //~^ ERROR expected type, found
+    //~^ ERROR invalid `struct` delimiters or `fn` call arguments
 }
index c8bad3b3bb502bbda95299b31c68c6e06dea2d10..fbff75e37d9f0864ff0630fbf99acbe6b6f058dd 100644 (file)
@@ -1,13 +1,18 @@
-error: expected type, found `42`
-  --> $DIR/issue-34255-1.rs:8:24
+error: invalid `struct` delimiters or `fn` call arguments
+  --> $DIR/issue-34255-1.rs:8:5
    |
 LL |     Test::Drill(field: 42);
-   |                      - ^^ expected type
-   |                      |
-   |                      tried to parse a type due to this type ascription
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+help: if `Test::Drill` is a struct, use braces as delimiters
+   |
+LL |     Test::Drill { field: 42 };
+   |                 ~           ~
+help: if `Test::Drill` is a function, use the arguments directly
+   |
+LL -     Test::Drill(field: 42);
+LL +     Test::Drill(42);
+   | 
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-34784.rs b/src/test/ui/issues/issue-34784.rs
deleted file mode 100644 (file)
index 98d9434..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-
-#![warn(pointer_structural_match)]
-#![allow(dead_code)]
-const C: *const u8 = &0;
-
-fn foo(x: *const u8) {
-    match x {
-        C => {}
-        _ => {}
-    }
-}
-
-const D: *const [u8; 4] = b"abcd";
-
-fn main() {
-    match D {
-        D => {}
-        _ => {}
-    }
-}
diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/issues/issue-35376.rs
deleted file mode 100644 (file)
index cc35213..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// check-pass
-#![feature(specialization)]
-//~^ WARN the feature `specialization` is incomplete
-
-fn main() {}
-
-pub trait Alpha<T> { }
-
-pub trait Beta {
-    type Event;
-}
-
-pub trait Delta {
-    type Handle;
-    fn process(&self);
-}
-
-pub struct Parent<A, T>(A, T);
-
-impl<A, T> Delta for Parent<A, T>
-where A: Alpha<T::Handle>,
-      T: Delta,
-      T::Handle: Beta<Event = <Handle as Beta>::Event> {
-    type Handle = Handle;
-    default fn process(&self) {
-        unimplemented!()
-    }
-}
-
-impl<A, T> Delta for Parent<A, T>
-where A: Alpha<T::Handle> + Alpha<Handle>,
-      T: Delta,
-      T::Handle: Beta<Event = <Handle as Beta>::Event> {
-      fn process(&self) {
-        unimplemented!()
-      }
-}
-
-pub struct Handle;
-
-impl Beta for Handle {
-    type Event = ();
-}
diff --git a/src/test/ui/issues/issue-35376.stderr b/src/test/ui/issues/issue-35376.stderr
deleted file mode 100644 (file)
index 835277d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-35376.rs:2:12
-   |
-LL | #![feature(specialization)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
-   = help: consider using `min_specialization` instead, which is more stable and complete
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/issues/issue-36768.rs b/src/test/ui/issues/issue-36768.rs
deleted file mode 100644 (file)
index f671cbc..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-// compile-flags:--test
-#![deny(private_in_public)]
-
-#[test] fn foo() {}
-mod foo {}
-
-#[test] fn core() {}
-extern crate core;
diff --git a/src/test/ui/issues/issue-37433.rs b/src/test/ui/issues/issue-37433.rs
deleted file mode 100644 (file)
index 1c362e8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// build-fail
-// ignore-emscripten no llvm_asm! support
-
-#![feature(llvm_asm)]
-#![allow(deprecated)] // llvm_asm!
-
-fn main() {
-    unsafe {
-        llvm_asm!("" :: "r"(""));
-        //~^ ERROR: invalid value for constraint in inline assembly
-    }
-}
diff --git a/src/test/ui/issues/issue-37433.stderr b/src/test/ui/issues/issue-37433.stderr
deleted file mode 100644 (file)
index 44a8eb3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/issue-37433.rs:9:29
-   |
-LL |         llvm_asm!("" :: "r"(""));
-   |                             ^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0669`.
diff --git a/src/test/ui/issues/issue-38002.rs b/src/test/ui/issues/issue-38002.rs
deleted file mode 100644 (file)
index fdb31fc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-// Check that constant ADTs are codegened OK, part k of N.
-
-enum Bar {
-    C
-}
-
-enum Foo {
-    A {},
-    B {
-        y: usize,
-        z: Bar
-    },
-}
-
-const LIST: [(usize, Foo); 2] = [
-    (51, Foo::B { y: 42, z: Bar::C }),
-    (52, Foo::B { y: 45, z: Bar::C }),
-];
-
-pub fn main() {
-    match LIST {
-        [
-            (51, Foo::B { y: 42, z: Bar::C }),
-            (52, Foo::B { y: 45, z: Bar::C })
-        ] => {}
-        _ => {
-            // I would want to print the enum here, but if
-            // the discriminant is garbage this causes an
-            // `unreachable` and silent process exit.
-            panic!("trivial match failed")
-        }
-    }
-}
diff --git a/src/test/ui/issues/issue-3935.rs b/src/test/ui/issues/issue-3935.rs
deleted file mode 100644 (file)
index e98d68e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-
-#[derive(PartialEq)]
-struct Bike {
-    name: String,
-}
-
-pub fn main() {
-    let town_bike = Bike { name: "schwinn".to_string() };
-    let my_bike = Bike { name: "surly".to_string() };
-
-    assert!(town_bike != my_bike);
-}
diff --git a/src/test/ui/issues/issue-41255.rs b/src/test/ui/issues/issue-41255.rs
deleted file mode 100644 (file)
index 9d7072f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// Matching against float literals should result in a linter error
-
-#![feature(exclusive_range_pattern)]
-#![feature(half_open_range_patterns)]
-#![allow(unused)]
-#![forbid(illegal_floating_point_literal_pattern)]
-
-fn main() {
-    let x = 42.0;
-    match x {
-        5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
-                   //~| WARNING hard error
-        5.0f32 => {}, //~ ERROR floating-point types cannot be used in patterns
-                      //~| WARNING hard error
-        -5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
-                    //~| WARNING hard error
-        1.0 .. 33.0 => {}, //~ ERROR floating-point types cannot be used in patterns
-                           //~| WARNING hard error
-                           //~| ERROR floating-point types cannot be used in patterns
-                           //~| WARNING hard error
-        39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns
-                             //~| ERROR floating-point types cannot be used in patterns
-                             //~| WARNING hard error
-                             //~| WARNING hard error
-
-        ..71.0 => {}
-        //~^ ERROR floating-point types cannot be used in patterns
-        //~| WARNING this was previously accepted by the compiler
-        ..=72.0 => {}
-        //~^ ERROR floating-point types cannot be used in patterns
-        //~| WARNING this was previously accepted by the compiler
-        71.0.. => {}
-        //~^ ERROR floating-point types cannot be used in patterns
-        //~| WARNING this was previously accepted by the compiler
-        _ => {},
-    };
-    let y = 5.0;
-    // Same for tuples
-    match (x, 5) {
-        (3.14, 1) => {}, //~ ERROR floating-point types cannot be used
-                         //~| WARNING hard error
-        _ => {},
-    }
-    // Or structs
-    struct Foo { x: f32 };
-    match (Foo { x }) {
-        Foo { x: 2.0 } => {}, //~ ERROR floating-point types cannot be used
-                              //~| WARNING hard error
-        _ => {},
-    }
-}
diff --git a/src/test/ui/issues/issue-41255.stderr b/src/test/ui/issues/issue-41255.stderr
deleted file mode 100644 (file)
index bf81c8d..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:11:9
-   |
-LL |         5.0 => {},
-   |         ^^^
-   |
-note: the lint level is defined here
-  --> $DIR/issue-41255.rs:6:11
-   |
-LL | #![forbid(illegal_floating_point_literal_pattern)]
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:13:9
-   |
-LL |         5.0f32 => {},
-   |         ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:15:10
-   |
-LL |         -5.0 => {},
-   |          ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:17:9
-   |
-LL |         1.0 .. 33.0 => {},
-   |         ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:17:16
-   |
-LL |         1.0 .. 33.0 => {},
-   |                ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:21:9
-   |
-LL |         39.0 ..= 70.0 => {},
-   |         ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:21:18
-   |
-LL |         39.0 ..= 70.0 => {},
-   |                  ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:26:11
-   |
-LL |         ..71.0 => {}
-   |           ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:29:12
-   |
-LL |         ..=72.0 => {}
-   |            ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:32:9
-   |
-LL |         71.0.. => {}
-   |         ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:40:10
-   |
-LL |         (3.14, 1) => {},
-   |          ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: floating-point types cannot be used in patterns
-  --> $DIR/issue-41255.rs:47:18
-   |
-LL |         Foo { x: 2.0 } => {},
-   |                  ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: aborting due to 12 previous errors
-
diff --git a/src/test/ui/issues/issue-42944.rs b/src/test/ui/issues/issue-42944.rs
deleted file mode 100644 (file)
index a440485..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-mod foo {
-    pub struct Bx(());
-}
-
-mod bar {
-    use foo::Bx;
-
-    fn foo() {
-        Bx(());
-        //~^ ERROR cannot initialize a tuple struct which contains private fields [E0423]
-    }
-}
-
-mod baz {
-    fn foo() {
-        Bx(());
-        //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` in this scope [E0425]
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-42944.stderr b/src/test/ui/issues/issue-42944.stderr
deleted file mode 100644 (file)
index 0084925..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0423]: cannot initialize a tuple struct which contains private fields
-  --> $DIR/issue-42944.rs:9:9
-   |
-LL |         Bx(());
-   |         ^^
-   |
-note: constructor is not visible here due to private fields
-  --> $DIR/issue-42944.rs:2:19
-   |
-LL |     pub struct Bx(());
-   |                   ^^ private field
-
-error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this scope
-  --> $DIR/issue-42944.rs:16:9
-   |
-LL |         Bx(());
-   |         ^^ not found in this scope
-   |
-help: consider importing this tuple struct
-   |
-LL |     use foo::Bx;
-   |
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0423, E0425.
-For more information about an error, try `rustc --explain E0423`.
index f187969ff4e86ad8595211ebf3e121b28b02f630..fa3b58e1279378353ddd0c6033eb9edee9518b0f 100644 (file)
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMu
 LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
    |             - captured outer variable
 LL |     id(Box::new(|| *v))
-   |                    ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+   |                 ---^^
+   |                 |  |
+   |                 |  move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+   |                 captured by this `FnMut` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.mir.stderr b/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.mir.stderr
deleted file mode 100644 (file)
index 9e9cbcf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-LL |         let f = |v: &mut Vec<_>| {
-LL |             unsafe {
-   |             ^^^^^^ unnecessary `unsafe` block
-   |
-note: the lint level is defined here
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8
-   |
-LL | #[deny(unused_unsafe)]
-   |        ^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-...
-LL |                 |w: &mut Vec<u32>| { unsafe {
-   |                                      ^^^^^^ unnecessary `unsafe` block
-
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-...
-LL |             |x: &mut Vec<u32>| { unsafe {
-   |                                  ^^^^^^ unnecessary `unsafe` block
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs b/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs
deleted file mode 100644 (file)
index ac1cfd6..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// revisions: mir thir
-// [thir]compile-flags: -Zthir-unsafeck
-
-#[deny(unused_unsafe)]
-fn main() {
-    let mut v = Vec::<i32>::with_capacity(24);
-
-    unsafe {
-        let f = |v: &mut Vec<_>| {
-            unsafe { //~ ERROR unnecessary `unsafe`
-                v.set_len(24);
-                |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe`
-                    w.set_len(32);
-                } };
-            }
-            |x: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe`
-                x.set_len(40);
-            } };
-        };
-
-        v.set_len(0);
-        f(&mut v);
-    }
-
-    |y: &mut Vec<u32>| { unsafe {
-        y.set_len(48);
-    } };
-}
diff --git a/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.thir.stderr b/src/test/ui/issues/issue-45107-unnecessary-unsafe-in-closure.thir.stderr
deleted file mode 100644 (file)
index 9e9cbcf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-LL |         let f = |v: &mut Vec<_>| {
-LL |             unsafe {
-   |             ^^^^^^ unnecessary `unsafe` block
-   |
-note: the lint level is defined here
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8
-   |
-LL | #[deny(unused_unsafe)]
-   |        ^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-...
-LL |                 |w: &mut Vec<u32>| { unsafe {
-   |                                      ^^^^^^ unnecessary `unsafe` block
-
-error: unnecessary `unsafe` block
-  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34
-   |
-LL |     unsafe {
-   |     ------ because it's nested under this `unsafe` block
-...
-LL |             |x: &mut Vec<u32>| { unsafe {
-   |                                  ^^^^^^ unnecessary `unsafe` block
-
-error: aborting due to 3 previous errors
-
index 8a6a199148c39c0848c491e93f86df20bdd94bb6..2e542644b70d4db676b8ab44bef27bf45efd0ca9 100644 (file)
@@ -4,7 +4,9 @@ error[E0593]: function is expected to take a single 0-tuple as argument, but it
 LL |     fn f(&self, _: ()) {
    |     ------------------ takes 2 distinct arguments
 LL |         None::<()>.map(Self::f);
-   |                        ^^^^^^^ expected function that takes a single 0-tuple as argument
+   |                    --- ^^^^^^^ expected function that takes a single 0-tuple as argument
+   |                    |
+   |                    required by a bound introduced by this call
 
 error: aborting due to previous error
 
index d9680a26e09c7446ba68c4dc67870f37ec17f385..acf7626c634e3c3100c82ee00e31d8e35701dc26 100644 (file)
@@ -5,7 +5,9 @@ LL |     pub fn new(foo: Option<i32>, _: ()) -> Foo {
    |     ------------------------------------------ takes 2 arguments
 ...
 LL |         self.foo.map(Foo::new)
-   |                      ^^^^^^^^ expected function that takes 1 argument
+   |                  --- ^^^^^^^^ expected function that takes 1 argument
+   |                  |
+   |                  required by a bound introduced by this call
 
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
   --> $DIR/issue-47706.rs:27:9
@@ -14,7 +16,9 @@ LL |     Bar(i32),
    |     -------- takes 1 argument
 ...
 LL |     foo(Qux::Bar);
-   |         ^^^^^^^^ expected function that takes 0 arguments
+   |     --- ^^^^^^^^ expected function that takes 0 arguments
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/issue-47706.rs:22:8
index bb74f0e0dc3c79bb3be14528954f84d36370c54c..35402dff675534f769bfe47a343d58b254ce7fb1 100644 (file)
@@ -6,7 +6,7 @@ fn missing_discourses() -> Result<isize, ()> {
 
 fn forbidden_narratives() -> Result<isize, ()> {
     missing_discourses()?
-    //~^ ERROR try expression alternatives have incompatible types
+    //~^ ERROR: `?` operator has incompatible types
 }
 
 fn main() {}
index 2c821aa23088d6d675b598da2a2cf6a787ae2611..0f61e03c3b58fb522d4d34d44407b74703719a54 100644 (file)
@@ -1,9 +1,10 @@
-error[E0308]: try expression alternatives have incompatible types
+error[E0308]: `?` operator has incompatible types
   --> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
    |
 LL |     missing_discourses()?
    |     ^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `isize`
    |
+   = note: `?` operator cannot convert from `isize` to `Result<isize, ()>`
    = note: expected enum `Result<isize, ()>`
               found type `isize`
 help: try removing this `?`
diff --git a/src/test/ui/issues/issue-53912.rs b/src/test/ui/issues/issue-53912.rs
deleted file mode 100644 (file)
index 65b6825..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// build-pass
-
-// This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
-// reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
-// symbol mangling fix produces the correct result.
-
-fn dummy() {}
-
-mod llvm {
-    pub(crate) struct Foo;
-}
-mod foo {
-    pub(crate) struct Foo<T>(T);
-
-    impl Foo<::llvm::Foo> {
-        pub(crate) fn foo() {
-            for _ in 0..0 {
-                for _ in &[::dummy()] {
-                    ::dummy();
-                    ::dummy();
-                    ::dummy();
-                }
-            }
-        }
-    }
-
-    pub(crate) fn foo() {
-        Foo::foo();
-        Foo::foo();
-    }
-}
-
-pub fn foo() {
-    foo::foo();
-}
-
-fn main() {}
index 3d7acee0a56eb9fbd3cf83c93ff43a3c179319bc..7ee5bc6ec617470f0acefbc8a9724bad42e47088 100644 (file)
@@ -3,6 +3,16 @@ error: missing trait in a trait impl
    |
 LL | impl for T {}
    |     ^
+   |
+help: add a trait here
+   |
+LL | impl Trait for T {}
+   |      +++++
+help: for an inherent impl, drop this `for`
+   |
+LL - impl for T {}
+LL + impl T {}
+   | 
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-56685.rs b/src/test/ui/issues/issue-56685.rs
deleted file mode 100644 (file)
index f320c99..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#![allow(dead_code)]
-#![deny(unused_variables)]
-
-// This test aims to check that unused variable suggestions update bindings in all
-// match arms.
-
-fn main() {
-    enum E {
-        A(i32,),
-        B(i32,),
-    }
-
-    match E::A(1) {
-        E::A(x) | E::B(x) => {}
-        //~^ ERROR unused variable: `x`
-    }
-
-    enum F {
-        A(i32, i32,),
-        B(i32, i32,),
-        C(i32, i32,),
-    }
-
-    let _ = match F::A(1, 2) {
-        F::A(x, y) | F::B(x, y) => { y },
-        //~^ ERROR unused variable: `x`
-        F::C(a, b) => { 3 }
-        //~^ ERROR unused variable: `a`
-        //~^^ ERROR unused variable: `b`
-    };
-
-    let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
-    //~^ ERROR unused variable: `x`
-        y
-    } else {
-        3
-    };
-
-    while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
-    //~^ ERROR unused variable: `x`
-        let _ = y;
-        break;
-    }
-}
diff --git a/src/test/ui/issues/issue-56685.stderr b/src/test/ui/issues/issue-56685.stderr
deleted file mode 100644 (file)
index ccf357d..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-error: unused variable: `x`
-  --> $DIR/issue-56685.rs:14:14
-   |
-LL |         E::A(x) | E::B(x) => {}
-   |              ^         ^
-   |
-note: the lint level is defined here
-  --> $DIR/issue-56685.rs:2:9
-   |
-LL | #![deny(unused_variables)]
-   |         ^^^^^^^^^^^^^^^^
-help: if this is intentional, prefix it with an underscore
-   |
-LL |         E::A(_x) | E::B(_x) => {}
-   |              ~~         ~~
-
-error: unused variable: `x`
-  --> $DIR/issue-56685.rs:25:14
-   |
-LL |         F::A(x, y) | F::B(x, y) => { y },
-   |              ^            ^
-   |
-help: if this is intentional, prefix it with an underscore
-   |
-LL |         F::A(_x, y) | F::B(_x, y) => { y },
-   |              ~~            ~~
-
-error: unused variable: `a`
-  --> $DIR/issue-56685.rs:27:14
-   |
-LL |         F::C(a, b) => { 3 }
-   |              ^ help: if this is intentional, prefix it with an underscore: `_a`
-
-error: unused variable: `b`
-  --> $DIR/issue-56685.rs:27:17
-   |
-LL |         F::C(a, b) => { 3 }
-   |                 ^ help: if this is intentional, prefix it with an underscore: `_b`
-
-error: unused variable: `x`
-  --> $DIR/issue-56685.rs:32:25
-   |
-LL |     let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
-   |                         ^            ^
-   |
-help: if this is intentional, prefix it with an underscore
-   |
-LL |     let _ = if let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
-   |                         ~~            ~~
-
-error: unused variable: `x`
-  --> $DIR/issue-56685.rs:39:20
-   |
-LL |     while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
-   |                    ^            ^
-   |
-help: if this is intentional, prefix it with an underscore
-   |
-LL |     while let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
-   |                    ~~            ~~
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs
deleted file mode 100644 (file)
index 0cf4b80..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// check-pass
-
-// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
-
-#![deny(unreachable_pub)]
-
-mod m {
-    mod imp {
-        pub fn f() {}
-    }
-
-    pub use self::imp::f;
-}
-
-pub use self::m::f;
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-5791.rs b/src/test/ui/issues/issue-5791.rs
deleted file mode 100644 (file)
index 3544160..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-#![warn(clashing_extern_declarations)]
-// pretty-expanded FIXME #23616
-
-extern "C" {
-    #[link_name = "malloc"]
-    fn malloc1(len: i32) -> *const u8;
-    #[link_name = "malloc"]
-    //~^ WARN `malloc2` redeclares `malloc` with a different signature
-    fn malloc2(len: i32, foo: i32) -> *const u8;
-}
-
-pub fn main() {}
diff --git a/src/test/ui/issues/issue-5791.stderr b/src/test/ui/issues/issue-5791.stderr
deleted file mode 100644 (file)
index cf60e60..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-warning: `malloc2` redeclares `malloc` with a different signature
-  --> $DIR/issue-5791.rs:9:5
-   |
-LL | /     #[link_name = "malloc"]
-LL | |     fn malloc1(len: i32) -> *const u8;
-   | |______________________________________- `malloc` previously declared here
-LL | /     #[link_name = "malloc"]
-LL | |
-LL | |     fn malloc2(len: i32, foo: i32) -> *const u8;
-   | |________________________________________________^ this signature doesn't match the previous declaration
-   |
-note: the lint level is defined here
-  --> $DIR/issue-5791.rs:3:9
-   |
-LL | #![warn(clashing_extern_declarations)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `unsafe extern "C" fn(i32) -> *const u8`
-              found `unsafe extern "C" fn(i32, i32) -> *const u8`
-
-warning: 1 warning emitted
-
index 90af47dfa79112c1dac825ed54967253d6262bc7..9b7fe1ef786f07721f557f1337f72e75b26348e2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>`
   --> $DIR/issue-59494.rs:21:22
    |
 LL |     let t8 = t8n(t7, t7p(f, g));
-   |                      ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>`
+   |              ---     ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>`
+   |              |
+   |              required by a bound introduced by this call
    |
    = help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>`
 note: required by a bound in `t8n`
index ac33cfd0402434095b36ca5b0fe27cd968077e5c..870b25014471d9402ef178545ca6d29e8747281d 100644 (file)
@@ -1,8 +1,10 @@
 error[E0277]: the trait bound `&u32: Foo` is not satisfied
-  --> $DIR/issue-60218.rs:18:5
+  --> $DIR/issue-60218.rs:18:27
    |
 LL |     trigger_error(vec![], |x: &u32| x)
-   |     ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32`
+   |     -------------         ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `trigger_error`
   --> $DIR/issue-60218.rs:13:72
index 2ee55105214586f991aafdb714c9999376d86140..34893cd8f19d908ffcc7f8b93750145dc5bda854 100644 (file)
@@ -2,10 +2,11 @@ error[E0631]: type mismatch in function arguments
   --> $DIR/issue-60283.rs:17:13
    |
 LL |     foo((), drop)
-   |             ^^^^
-   |             |
-   |             expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |             found signature of `fn(()) -> _`
+   |     ---     ^^^^
+   |     |       |
+   |     |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
+   |     |       found signature of `fn(()) -> _`
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/issue-60283.rs:12:16
@@ -20,7 +21,9 @@ error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be kn
   --> $DIR/issue-60283.rs:17:13
    |
 LL |     foo((), drop)
-   |             ^^^^ doesn't have a size known at compile-time
+   |     ---     ^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `<() as Trait<'_>>::Item`
 note: required by a bound in `std::mem::drop`
index 59a521c7360faaefb8e8ab376e301e9b12c69756..282e236d3d021d84217a3ee3195f2df31e70efc0 100644 (file)
@@ -8,7 +8,9 @@ error[E0277]: the trait bound `(): _Func<_>` is not satisfied
   --> $DIR/issue-66353.rs:12:41
    |
 LL |     _Func::< <() as _A>::AssocT >::func(());
-   |                                         ^^ the trait `_Func<_>` is not implemented for `()`
+   |     ----------------------------------- ^^ the trait `_Func<_>` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by `_Func::func`
   --> $DIR/issue-66353.rs:4:5
diff --git a/src/test/ui/issues/issue-74614.rs b/src/test/ui/issues/issue-74614.rs
deleted file mode 100644 (file)
index 8b0c00b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// compile-flags:-Zpolymorphize=on
-// build-pass
-
-fn test<T>() {
-    std::mem::size_of::<T>();
-}
-
-pub fn foo<T>(_: T) -> &'static fn() {
-    &(test::<T> as fn())
-}
-
-fn outer<T>() {
-    foo(|| ());
-}
-
-fn main() {
-    outer::<u8>();
-}
diff --git a/src/test/ui/issues/issue-78720.rs b/src/test/ui/issues/issue-78720.rs
deleted file mode 100644 (file)
index 4cdb9f4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-fn server() -> impl {
-//~^ ERROR at least one trait must be specified
-    ().map2(|| "")
-}
-
-trait FilterBase2 {
-    fn map2<F>(self, f: F) -> Map2<F> {}
-    //~^ ERROR mismatched types
-    //~^^ ERROR the size for values of type `Self` cannot be known at compilation time
-}
-
-struct Map2<Segment2> {
-    _func: F,
-    //~^ ERROR cannot find type `F` in this scope
-}
-
-impl<F> FilterBase2 for F {}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-78720.stderr b/src/test/ui/issues/issue-78720.stderr
deleted file mode 100644 (file)
index 3dd1387..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-error: at least one trait must be specified
-  --> $DIR/issue-78720.rs:1:16
-   |
-LL | fn server() -> impl {
-   |                ^^^^
-
-error[E0412]: cannot find type `F` in this scope
-  --> $DIR/issue-78720.rs:13:12
-   |
-LL |     _func: F,
-   |            ^
-   |
-  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL | pub trait Fn<Args>: FnMut<Args> {
-   | ------------------------------- similarly named trait `Fn` defined here
-   |
-help: a trait with a similar name exists
-   |
-LL |     _func: Fn,
-   |            ~~
-help: you might be missing a type parameter
-   |
-LL | struct Map2<Segment2, F> {
-   |                     +++
-
-error[E0308]: mismatched types
-  --> $DIR/issue-78720.rs:7:39
-   |
-LL |     fn map2<F>(self, f: F) -> Map2<F> {}
-   |                                       ^^ expected struct `Map2`, found `()`
-   |
-   = note: expected struct `Map2<F>`
-           found unit type `()`
-
-error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/issue-78720.rs:7:16
-   |
-LL |     fn map2<F>(self, f: F) -> Map2<F> {}
-   |                ^^^^ doesn't have a size known at compile-time
-   |
-   = help: unsized fn params are gated as an unstable feature
-help: consider further restricting `Self`
-   |
-LL |     fn map2<F>(self, f: F) -> Map2<F> where Self: Sized {}
-   |                                       +++++++++++++++++
-help: function arguments must have a statically known size, borrowed types always have a known size
-   |
-LL |     fn map2<F>(&self, f: F) -> Map2<F> {}
-   |                +
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0277, E0308, E0412.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-79593.rs b/src/test/ui/issues/issue-79593.rs
deleted file mode 100644 (file)
index b94278b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-mod foo {
-    pub struct Pub { private: () }
-
-    pub enum Enum {
-        Variant { x: (), y: () },
-        Other
-    }
-
-    fn correct() {
-        Pub {};
-        //~^ ERROR missing field `private` in initializer of `Pub`
-        Enum::Variant { x: () };
-        //~^ ERROR missing field `y` in initializer of `Enum`
-    }
-}
-
-fn correct() {
-    foo::Pub {};
-    //~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields
-}
-
-fn wrong() {
-    foo::Enum::Variant { x: () };
-    //~^ ERROR missing field `y` in initializer of `Enum`
-    foo::Enum::Variant { };
-    //~^ ERROR missing fields `x` and `y` in initializer of `Enum`
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-79593.stderr b/src/test/ui/issues/issue-79593.stderr
deleted file mode 100644 (file)
index b8c7d4f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0063]: missing field `private` in initializer of `Pub`
-  --> $DIR/issue-79593.rs:10:9
-   |
-LL |         Pub {};
-   |         ^^^ missing `private`
-
-error[E0063]: missing field `y` in initializer of `Enum`
-  --> $DIR/issue-79593.rs:12:9
-   |
-LL |         Enum::Variant { x: () };
-   |         ^^^^^^^^^^^^^ missing `y`
-
-error: cannot construct `Pub` with struct literal syntax due to inaccessible fields
-  --> $DIR/issue-79593.rs:18:5
-   |
-LL |     foo::Pub {};
-   |     ^^^^^^^^
-
-error[E0063]: missing field `y` in initializer of `Enum`
-  --> $DIR/issue-79593.rs:23:5
-   |
-LL |     foo::Enum::Variant { x: () };
-   |     ^^^^^^^^^^^^^^^^^^ missing `y`
-
-error[E0063]: missing fields `x` and `y` in initializer of `Enum`
-  --> $DIR/issue-79593.rs:25:5
-   |
-LL |     foo::Enum::Variant { };
-   |     ^^^^^^^^^^^^^^^^^^ missing `x` and `y`
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/issues/issue-79744.rs b/src/test/ui/issues/issue-79744.rs
deleted file mode 100644 (file)
index e9725a0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-fn main() {
-    let elem = 6i8;
-    let e2 = 230;
-    //~^ ERROR literal out of range for `i8`
-    //~| HELP consider using the type `u8` instead
-
-    let mut vec = Vec::new();
-
-    vec.push(e2);
-    vec.push(elem);
-
-    println!("{:?}", vec);
-}
diff --git a/src/test/ui/issues/issue-79744.stderr b/src/test/ui/issues/issue-79744.stderr
deleted file mode 100644 (file)
index 6f6dd44..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error: literal out of range for `i8`
-  --> $DIR/issue-79744.rs:3:14
-   |
-LL |     let e2 = 230;
-   |              ^^^
-   |
-   = note: `#[deny(overflowing_literals)]` on by default
-   = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
-
-error: aborting due to previous error
-
index fc9418b36b633bbe2edc829b3f39a3888a704c27..0ec5e73f39a855ced018873205deb38b447b0708 100644 (file)
@@ -20,7 +20,9 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation
   --> $DIR/issue-87199.rs:18:22
    |
 LL |     ref_arg::<[i32]>(&[5]);
-   |                      ^^^^ doesn't have a size known at compile-time
+   |     ---------------- ^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `[i32]`
 note: required by a bound in `ref_arg`
diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs
deleted file mode 100644 (file)
index ecfa5c6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-trait Foo {
-    type T;
-    fn foo(&self, t: Self::T);
-//~^ NOTE expected 0 type parameters
-}
-
-impl Foo for u32 {
-    type T = ();
-
-    fn foo(&self, t: impl Clone) {}
-//~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
-//~| NOTE found 1 type parameter
-//~| NOTE `impl Trait` introduces an implicit type parameter
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr
deleted file mode 100644 (file)
index 30322f8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/type-arg-mismatch-due-to-impl-trait.rs:10:22
-   |
-LL |     fn foo(&self, t: Self::T);
-   |           - expected 0 type parameters
-...
-LL |     fn foo(&self, t: impl Clone) {}
-   |                      ^^^^^^^^^^
-   |                      |
-   |                      found 1 type parameter
-   |                      `impl Trait` introduces an implicit type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0049`.
index 60ad68cec414393b94752330474232c6c041e23a..89975e9683dbf4eadc3456d9dffcd5504f1135bf 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
   --> $DIR/kindck-impl-type-params-2.rs:13:16
    |
 LL |     take_param(&x);
-   |                ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
   --> $DIR/kindck-impl-type-params-2.rs:6:14
index ac43c549d8d92f8e89eb553a4d660c8d92bd2e51..016cd393c859195dd812648915ceb3ad76c14741 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
   --> $DIR/kindck-inherited-copy-bound.rs:21:16
    |
 LL |     take_param(&x);
-   |                ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
   --> $DIR/kindck-inherited-copy-bound.rs:14:14
index a486ab17c888f07a0d4c4f485f73b0c948c08e5a..eaf34dff41bf0f8c083dd1b59da0a22a707846f5 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
   --> $DIR/kindck-inherited-copy-bound.rs:21:16
    |
 LL |     take_param(&x);
-   |                ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
   --> $DIR/kindck-inherited-copy-bound.rs:14:14
diff --git a/src/test/ui/lifetimes/issue-77175.rs b/src/test/ui/lifetimes/issue-77175.rs
new file mode 100644 (file)
index 0000000..2282752
--- /dev/null
@@ -0,0 +1,19 @@
+#[deny(single_use_lifetimes)]
+// edition:2018
+// check-pass
+
+// Prior to the fix, the compiler complained that the 'a lifetime was only used
+// once. This was obviously wrong since the lifetime is used twice: For the s3
+// parameter and the return type. The issue was caused by the compiler
+// desugaring the async function into a generator that uses only a single
+// lifetime, which then the validator complained about becauase of the
+// single_use_lifetimes constraints.
+async fn bar<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
+    s3
+}
+
+fn foo<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
+    s3
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/enable-unstable-lib-feature.rs b/src/test/ui/lint/enable-unstable-lib-feature.rs
new file mode 100644 (file)
index 0000000..aa6a973
--- /dev/null
@@ -0,0 +1,13 @@
+// Test that enabling an unstable feature disables warnings
+
+// aux-build:stability-cfg2.rs
+
+#![feature(unstable_test_feature)]
+#![deny(non_snake_case)] // To trigger a hard error
+
+// Shouldn't generate a warning about unstable features
+extern crate stability_cfg2;
+
+pub fn BOGUS() { } //~ ERROR
+
+pub fn main() { }
diff --git a/src/test/ui/lint/enable-unstable-lib-feature.stderr b/src/test/ui/lint/enable-unstable-lib-feature.stderr
new file mode 100644 (file)
index 0000000..bb4e928
--- /dev/null
@@ -0,0 +1,14 @@
+error: function `BOGUS` should have a snake case name
+  --> $DIR/enable-unstable-lib-feature.rs:11:8
+   |
+LL | pub fn BOGUS() { }
+   |        ^^^^^ help: convert the identifier to snake case: `bogus`
+   |
+note: the lint level is defined here
+  --> $DIR/enable-unstable-lib-feature.rs:6:9
+   |
+LL | #![deny(non_snake_case)] // To trigger a hard error
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/issue-57410.rs b/src/test/ui/lint/issue-57410.rs
new file mode 100644 (file)
index 0000000..0cf4b80
--- /dev/null
@@ -0,0 +1,17 @@
+// check-pass
+
+// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
+
+#![deny(unreachable_pub)]
+
+mod m {
+    mod imp {
+        pub fn f() {}
+    }
+
+    pub use self::imp::f;
+}
+
+pub use self::m::f;
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-79744.rs b/src/test/ui/lint/issue-79744.rs
new file mode 100644 (file)
index 0000000..e9725a0
--- /dev/null
@@ -0,0 +1,13 @@
+fn main() {
+    let elem = 6i8;
+    let e2 = 230;
+    //~^ ERROR literal out of range for `i8`
+    //~| HELP consider using the type `u8` instead
+
+    let mut vec = Vec::new();
+
+    vec.push(e2);
+    vec.push(elem);
+
+    println!("{:?}", vec);
+}
diff --git a/src/test/ui/lint/issue-79744.stderr b/src/test/ui/lint/issue-79744.stderr
new file mode 100644 (file)
index 0000000..6f6dd44
--- /dev/null
@@ -0,0 +1,12 @@
+error: literal out of range for `i8`
+  --> $DIR/issue-79744.rs:3:14
+   |
+LL |     let e2 = 230;
+   |              ^^^
+   |
+   = note: `#[deny(overflowing_literals)]` on by default
+   = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/llvm-asm/issue-37433.rs b/src/test/ui/llvm-asm/issue-37433.rs
new file mode 100644 (file)
index 0000000..1c362e8
--- /dev/null
@@ -0,0 +1,12 @@
+// build-fail
+// ignore-emscripten no llvm_asm! support
+
+#![feature(llvm_asm)]
+#![allow(deprecated)] // llvm_asm!
+
+fn main() {
+    unsafe {
+        llvm_asm!("" :: "r"(""));
+        //~^ ERROR: invalid value for constraint in inline assembly
+    }
+}
diff --git a/src/test/ui/llvm-asm/issue-37433.stderr b/src/test/ui/llvm-asm/issue-37433.stderr
new file mode 100644 (file)
index 0000000..44a8eb3
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/issue-37433.rs:9:29
+   |
+LL |         llvm_asm!("" :: "r"(""));
+   |                             ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0669`.
diff --git a/src/test/ui/macros/auxiliary/define-macro.rs b/src/test/ui/macros/auxiliary/define-macro.rs
new file mode 100644 (file)
index 0000000..4956907
--- /dev/null
@@ -0,0 +1,6 @@
+#[macro_export]
+macro_rules! define_macro {
+    ($i:ident) => {
+        macro_rules! $i { () => {} }
+    }
+}
diff --git a/src/test/ui/macros/out-of-order-shadowing.rs b/src/test/ui/macros/out-of-order-shadowing.rs
new file mode 100644 (file)
index 0000000..a0d1a97
--- /dev/null
@@ -0,0 +1,10 @@
+// aux-build:define-macro.rs
+
+macro_rules! bar { () => {} }
+define_macro!(bar);
+bar!(); //~ ERROR `bar` is ambiguous
+
+macro_rules! m { () => { #[macro_use] extern crate define_macro; } }
+m!();
+
+fn main() {}
diff --git a/src/test/ui/macros/out-of-order-shadowing.stderr b/src/test/ui/macros/out-of-order-shadowing.stderr
new file mode 100644 (file)
index 0000000..1db31e0
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0659]: `bar` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/out-of-order-shadowing.rs:5:1
+   |
+LL | bar!();
+   | ^^^ ambiguous name
+   |
+note: `bar` could refer to the macro defined here
+  --> $DIR/out-of-order-shadowing.rs:4:1
+   |
+LL | define_macro!(bar);
+   | ^^^^^^^^^^^^^^^^^^^
+note: `bar` could also refer to the macro defined here
+  --> $DIR/out-of-order-shadowing.rs:3:1
+   |
+LL | macro_rules! bar { () => {} }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `define_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/match/guards.rs b/src/test/ui/match/guards.rs
new file mode 100644 (file)
index 0000000..10a4bb6
--- /dev/null
@@ -0,0 +1,20 @@
+// run-pass
+
+#![allow(non_shorthand_field_patterns)]
+
+#[derive(Copy, Clone)]
+struct Pair { x: isize, y: isize }
+
+pub fn main() {
+    let a: isize =
+        match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } };
+    assert_eq!(a, 2);
+
+    let b: isize =
+        match (Pair {x: 10, y: 20}) {
+          x if x.x < 5 && x.y < 5 => { 1 }
+          Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
+          Pair {x: _x, y: _y} => { 3 }
+        };
+    assert_eq!(b, 2);
+}
diff --git a/src/test/ui/match/issue-33498.rs b/src/test/ui/match/issue-33498.rs
new file mode 100644 (file)
index 0000000..9c8a97e
--- /dev/null
@@ -0,0 +1,11 @@
+// run-pass
+#![allow(unused_variables)]
+pub fn main() {
+    let x = (0, 2);
+
+    match x {
+        (0, ref y) => {}
+        (y, 0) => {}
+        _ => (),
+    }
+}
diff --git a/src/test/ui/match/issue-41255.rs b/src/test/ui/match/issue-41255.rs
new file mode 100644 (file)
index 0000000..9d7072f
--- /dev/null
@@ -0,0 +1,51 @@
+// Matching against float literals should result in a linter error
+
+#![feature(exclusive_range_pattern)]
+#![feature(half_open_range_patterns)]
+#![allow(unused)]
+#![forbid(illegal_floating_point_literal_pattern)]
+
+fn main() {
+    let x = 42.0;
+    match x {
+        5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+                   //~| WARNING hard error
+        5.0f32 => {}, //~ ERROR floating-point types cannot be used in patterns
+                      //~| WARNING hard error
+        -5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+                    //~| WARNING hard error
+        1.0 .. 33.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+                           //~| WARNING hard error
+                           //~| ERROR floating-point types cannot be used in patterns
+                           //~| WARNING hard error
+        39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+                             //~| ERROR floating-point types cannot be used in patterns
+                             //~| WARNING hard error
+                             //~| WARNING hard error
+
+        ..71.0 => {}
+        //~^ ERROR floating-point types cannot be used in patterns
+        //~| WARNING this was previously accepted by the compiler
+        ..=72.0 => {}
+        //~^ ERROR floating-point types cannot be used in patterns
+        //~| WARNING this was previously accepted by the compiler
+        71.0.. => {}
+        //~^ ERROR floating-point types cannot be used in patterns
+        //~| WARNING this was previously accepted by the compiler
+        _ => {},
+    };
+    let y = 5.0;
+    // Same for tuples
+    match (x, 5) {
+        (3.14, 1) => {}, //~ ERROR floating-point types cannot be used
+                         //~| WARNING hard error
+        _ => {},
+    }
+    // Or structs
+    struct Foo { x: f32 };
+    match (Foo { x }) {
+        Foo { x: 2.0 } => {}, //~ ERROR floating-point types cannot be used
+                              //~| WARNING hard error
+        _ => {},
+    }
+}
diff --git a/src/test/ui/match/issue-41255.stderr b/src/test/ui/match/issue-41255.stderr
new file mode 100644 (file)
index 0000000..bf81c8d
--- /dev/null
@@ -0,0 +1,115 @@
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:11:9
+   |
+LL |         5.0 => {},
+   |         ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-41255.rs:6:11
+   |
+LL | #![forbid(illegal_floating_point_literal_pattern)]
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:13:9
+   |
+LL |         5.0f32 => {},
+   |         ^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:15:10
+   |
+LL |         -5.0 => {},
+   |          ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:17:9
+   |
+LL |         1.0 .. 33.0 => {},
+   |         ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:17:16
+   |
+LL |         1.0 .. 33.0 => {},
+   |                ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:21:9
+   |
+LL |         39.0 ..= 70.0 => {},
+   |         ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:21:18
+   |
+LL |         39.0 ..= 70.0 => {},
+   |                  ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:26:11
+   |
+LL |         ..71.0 => {}
+   |           ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:29:12
+   |
+LL |         ..=72.0 => {}
+   |            ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:32:9
+   |
+LL |         71.0.. => {}
+   |         ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:40:10
+   |
+LL |         (3.14, 1) => {},
+   |          ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+  --> $DIR/issue-41255.rs:47:18
+   |
+LL |         Foo { x: 2.0 } => {},
+   |                  ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/match/issue-56685.rs b/src/test/ui/match/issue-56685.rs
new file mode 100644 (file)
index 0000000..f320c99
--- /dev/null
@@ -0,0 +1,44 @@
+#![allow(dead_code)]
+#![deny(unused_variables)]
+
+// This test aims to check that unused variable suggestions update bindings in all
+// match arms.
+
+fn main() {
+    enum E {
+        A(i32,),
+        B(i32,),
+    }
+
+    match E::A(1) {
+        E::A(x) | E::B(x) => {}
+        //~^ ERROR unused variable: `x`
+    }
+
+    enum F {
+        A(i32, i32,),
+        B(i32, i32,),
+        C(i32, i32,),
+    }
+
+    let _ = match F::A(1, 2) {
+        F::A(x, y) | F::B(x, y) => { y },
+        //~^ ERROR unused variable: `x`
+        F::C(a, b) => { 3 }
+        //~^ ERROR unused variable: `a`
+        //~^^ ERROR unused variable: `b`
+    };
+
+    let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+    //~^ ERROR unused variable: `x`
+        y
+    } else {
+        3
+    };
+
+    while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+    //~^ ERROR unused variable: `x`
+        let _ = y;
+        break;
+    }
+}
diff --git a/src/test/ui/match/issue-56685.stderr b/src/test/ui/match/issue-56685.stderr
new file mode 100644 (file)
index 0000000..ccf357d
--- /dev/null
@@ -0,0 +1,63 @@
+error: unused variable: `x`
+  --> $DIR/issue-56685.rs:14:14
+   |
+LL |         E::A(x) | E::B(x) => {}
+   |              ^         ^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-56685.rs:2:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         E::A(_x) | E::B(_x) => {}
+   |              ~~         ~~
+
+error: unused variable: `x`
+  --> $DIR/issue-56685.rs:25:14
+   |
+LL |         F::A(x, y) | F::B(x, y) => { y },
+   |              ^            ^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         F::A(_x, y) | F::B(_x, y) => { y },
+   |              ~~            ~~
+
+error: unused variable: `a`
+  --> $DIR/issue-56685.rs:27:14
+   |
+LL |         F::C(a, b) => { 3 }
+   |              ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/issue-56685.rs:27:17
+   |
+LL |         F::C(a, b) => { 3 }
+   |                 ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `x`
+  --> $DIR/issue-56685.rs:32:25
+   |
+LL |     let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+   |                         ^            ^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |     let _ = if let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
+   |                         ~~            ~~
+
+error: unused variable: `x`
+  --> $DIR/issue-56685.rs:39:20
+   |
+LL |     while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+   |                    ^            ^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |     while let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
+   |                    ~~            ~~
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/mid-path-type-params.rs b/src/test/ui/mid-path-type-params.rs
deleted file mode 100644 (file)
index a812820..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-// pretty-expanded FIXME #23616
-
-struct S<T> {
-    contents: T,
-}
-
-impl<T> S<T> {
-    fn new<U>(x: T, _: U) -> S<T> {
-        S {
-            contents: x,
-        }
-    }
-}
-
-trait Trait<T> {
-    fn new<U>(x: T, y: U) -> Self;
-}
-
-struct S2 {
-    contents: isize,
-}
-
-impl Trait<isize> for S2 {
-    fn new<U>(x: isize, _: U) -> S2 {
-        S2 {
-            contents: x,
-        }
-    }
-}
-
-pub fn main() {
-    let _ = S::<isize>::new::<f64>(1, 1.0);
-    let _: S2 = Trait::<isize>::new::<f64>(1, 1.0);
-}
diff --git a/src/test/ui/mir/remove-zsts-query-cycle.rs b/src/test/ui/mir/remove-zsts-query-cycle.rs
new file mode 100644 (file)
index 0000000..8f93c6c
--- /dev/null
@@ -0,0 +1,16 @@
+// Regression test for #88972. Used to cause a query cycle:
+//   optimized mir -> remove zsts -> layout of a generator -> optimized mir.
+//
+// edition:2018
+// compile-flags: --crate-type=lib
+// build-pass
+
+pub async fn listen() -> Result<(), std::io::Error> {
+    let f = do_async();
+    std::mem::forget(f);
+    Ok(())
+}
+
+pub async fn do_async() {
+    listen().await.unwrap()
+}
index c8e81c93e2cbd432db2ac1575317f6b1dd83b3a8..1f2e169c6813c9eefc4be9839f08a7c8576a141c 100644 (file)
@@ -33,7 +33,9 @@ LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     foo(f);
-   |         ^ expected signature of `fn(usize) -> _`
+   |     --- ^ expected signature of `fn(usize) -> _`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/E0631.rs:3:11
@@ -48,7 +50,9 @@ LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     bar(f);
-   |         ^ expected signature of `fn(usize) -> _`
+   |     --- ^ expected signature of `fn(usize) -> _`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `bar`
   --> $DIR/E0631.rs:4:11
index 679001724640490576203304ed877226486dfb2e..e8fcf80e940d29b7c152fd791fa359e9978f2002 100644 (file)
@@ -119,7 +119,9 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it
   --> $DIR/closure-arg-count.rs:24:57
    |
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
-   |                                                         ^^^ expected function that takes a single 2-tuple as argument
+   |                                                     --- ^^^ expected function that takes a single 2-tuple as argument
+   |                                                     |
+   |                                                     required by a bound introduced by this call
 ...
 LL | fn foo() {}
    | -------- takes 0 arguments
@@ -130,13 +132,17 @@ error[E0593]: closure is expected to take a single 2-tuple as argument, but it t
 LL |     let bar = |i, x, y| i;
    |               --------- takes 3 distinct arguments
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
-   |                                                         ^^^ expected closure that takes a single 2-tuple as argument
+   |                                                     --- ^^^ expected closure that takes a single 2-tuple as argument
+   |                                                     |
+   |                                                     required by a bound introduced by this call
 
 error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
   --> $DIR/closure-arg-count.rs:29:57
    |
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
-   |                                                         ^^^ expected function that takes a single 2-tuple as argument
+   |                                                     --- ^^^ expected function that takes a single 2-tuple as argument
+   |                                                     |
+   |                                                     required by a bound introduced by this call
 ...
 LL | fn qux(x: usize, y: usize) {}
    | -------------------------- takes 2 distinct arguments
@@ -145,13 +151,17 @@ error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
   --> $DIR/closure-arg-count.rs:32:45
    |
 LL |     let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
-   |                                             ^^^^^^^^^^^^^^^^^^ expected function that takes 1 argument
+   |                                         --- ^^^^^^^^^^^^^^^^^^ expected function that takes 1 argument
+   |                                         |
+   |                                         required by a bound introduced by this call
 
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
   --> $DIR/closure-arg-count.rs:35:10
    |
 LL |     call(Foo);
-   |          ^^^ expected function that takes 0 arguments
+   |     ---- ^^^ expected function that takes 0 arguments
+   |     |
+   |     required by a bound introduced by this call
 ...
 LL | struct Foo(u8);
    | --------------- takes 1 argument
index afde894b3044d0cd2635b4921cfaf07612c6620c..ce1dde94b5dd021a74f7c42577121fb6745ea1fc 100644 (file)
@@ -5,7 +5,9 @@ LL | fn takes_mut(x: &mut isize) { }
    | --------------------------- found signature of `for<'r> fn(&'r mut isize) -> _`
 ...
 LL |     apply(&3, takes_mut);
-   |               ^^^^^^^^^ expected signature of `fn(&{integer}) -> _`
+   |     -----     ^^^^^^^^^ expected signature of `fn(&{integer}) -> _`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `apply`
   --> $DIR/fn-variance-1.rs:5:37
@@ -20,7 +22,9 @@ LL | fn takes_imm(x: &isize) { }
    | ----------------------- found signature of `for<'r> fn(&'r isize) -> _`
 ...
 LL |     apply(&mut 3, takes_imm);
-   |                   ^^^^^^^^^ expected signature of `fn(&mut {integer}) -> _`
+   |     -----         ^^^^^^^^^ expected signature of `fn(&mut {integer}) -> _`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `apply`
   --> $DIR/fn-variance-1.rs:5:37
index ad59462e9bd441a1613da27dd2d69332b727f293..44ec28f53cc62d5a6ca4cbbc9120378206b1982a 100644 (file)
@@ -16,5 +16,6 @@ pub fn main() {
     let z = call_it(3, f);
     //~^ ERROR type mismatch
     //~| NOTE expected signature of `fn(isize, isize) -> _`
+    //~| NOTE required by a bound introduced by this call
     println!("{}", z);
 }
index 4406f8a9e58b40fa5b793fdd1c585380d01c2ed9..f9ef5bc4e39b3680f893345afe5496355d9574a8 100644 (file)
@@ -5,7 +5,9 @@ LL |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
 LL |
 LL |     let z = call_it(3, f);
-   |                        ^ expected signature of `fn(isize, isize) -> _`
+   |             -------    ^ expected signature of `fn(isize, isize) -> _`
+   |             |
+   |             required by a bound introduced by this call
    |
 note: required by a bound in `call_it`
   --> $DIR/unboxed-closures-vtable-mismatch.rs:7:14
index 9427ba546a9c10468153db4e4547826cf02713d0..e12af2d45274315fcdef2ad9bfed6f3d1e4f2784 100644 (file)
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
 LL |     let i = box 3;
    |         - captured outer variable
 LL |     let _f = to_fn(|| test(i));
-   |                            ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |                    --------^-
+   |                    |       |
+   |                    |       move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |                    captured by this `Fn` closure
 
 error: aborting due to previous error
 
index 172e257ebf04a5b007b91c7a38f833b7c3dc3d72..b3c77b13eafb4e0e352fe249769d8c533d11d8f8 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `Cell<i32>` cannot be shared between threads safely
   --> $DIR/mutexguard-sync.rs:11:15
    |
 LL |     test_sync(guard);
-   |               ^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |     --------- ^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
    = note: required because of the requirements on the impl of `Sync` for `MutexGuard<'_, Cell<i32>>`
index e4e1071638876489ce44c60dec59d88f671efc59..b610857229201a156a3c5967e7cf11625dfd2f7d 100644 (file)
@@ -100,7 +100,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:33:11
    |
 LL |     check(m1::S{});
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -112,7 +114,9 @@ error[E0277]: the trait bound `c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:35:11
    |
 LL |     check(m2::S{});
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::S`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `c::S`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -124,7 +128,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:36:11
    |
 LL |     check(m2::S);
-   |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -136,7 +142,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:39:11
    |
 LL |     check(xm1::S{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -148,7 +156,9 @@ error[E0277]: the trait bound `namespace_mix::c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:41:11
    |
 LL |     check(xm2::S{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -160,7 +170,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:42:11
    |
 LL |     check(xm2::S);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -172,7 +184,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:55:11
    |
 LL |     check(m3::TS{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -184,7 +198,9 @@ error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfi
   --> $DIR/namespace-mix.rs:56:11
    |
 LL |     check(m3::TS);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -196,7 +212,9 @@ error[E0277]: the trait bound `c::TS: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:57:11
    |
 LL |     check(m4::TS{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::TS`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::TS`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -208,7 +226,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:58:11
    |
 LL |     check(m4::TS);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -220,7 +240,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:61:11
    |
 LL |     check(xm3::TS{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -232,7 +254,9 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::T
   --> $DIR/namespace-mix.rs:62:11
    |
 LL |     check(xm3::TS);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -244,7 +268,9 @@ error[E0277]: the trait bound `namespace_mix::c::TS: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:63:11
    |
 LL |     check(xm4::TS{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -256,7 +282,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:64:11
    |
 LL |     check(xm4::TS);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -268,7 +296,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:77:11
    |
 LL |     check(m5::US{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -280,7 +310,9 @@ error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:78:11
    |
 LL |     check(m5::US);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -292,7 +324,9 @@ error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:79:11
    |
 LL |     check(m6::US{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -304,7 +338,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:80:11
    |
 LL |     check(m6::US);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -316,7 +352,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:83:11
    |
 LL |     check(xm5::US{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -328,7 +366,9 @@ error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:84:11
    |
 LL |     check(xm5::US);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -340,7 +380,9 @@ error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:85:11
    |
 LL |     check(xm6::US{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -352,7 +394,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:86:11
    |
 LL |     check(xm6::US);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -364,7 +408,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:99:11
    |
 LL |     check(m7::V{});
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -376,7 +422,9 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:101:11
    |
 LL |     check(m8::V{});
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -388,7 +436,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:102:11
    |
 LL |     check(m8::V);
-   |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -400,7 +450,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:105:11
    |
 LL |     check(xm7::V{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -412,7 +464,9 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:107:11
    |
 LL |     check(xm8::V{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -424,7 +478,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:108:11
    |
 LL |     check(xm8::V);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -436,7 +492,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:121:11
    |
 LL |     check(m9::TV{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -448,7 +506,9 @@ error[E0277]: the trait bound `fn() -> c::E {c::E::TV}: Impossible` is not satis
   --> $DIR/namespace-mix.rs:122:11
    |
 LL |     check(m9::TV);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -460,7 +520,9 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:123:11
    |
 LL |     check(mA::TV{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -472,7 +534,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:124:11
    |
 LL |     check(mA::TV);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -484,7 +548,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:127:11
    |
 LL |     check(xm9::TV{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -496,7 +562,9 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::
   --> $DIR/namespace-mix.rs:128:11
    |
 LL |     check(xm9::TV);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -508,7 +576,9 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:129:11
    |
 LL |     check(xmA::TV{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -520,7 +590,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:130:11
    |
 LL |     check(xmA::TV);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -532,7 +604,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:143:11
    |
 LL |     check(mB::UV{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -544,7 +618,9 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:144:11
    |
 LL |     check(mB::UV);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -556,7 +632,9 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:145:11
    |
 LL |     check(mC::UV{});
-   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     ----- ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -568,7 +646,9 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:146:11
    |
 LL |     check(mC::UV);
-   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     ----- ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -580,7 +660,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:149:11
    |
 LL |     check(xmB::UV{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -592,7 +674,9 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:150:11
    |
 LL |     check(xmB::UV);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -604,7 +688,9 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:151:11
    |
 LL |     check(xmC::UV{});
-   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     ----- ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
@@ -616,7 +702,9 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:152:11
    |
 LL |     check(xmC::UV);
-   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     ----- ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `check`
   --> $DIR/namespace-mix.rs:21:13
diff --git a/src/test/ui/never_type/expr-empty-ret.rs b/src/test/ui/never_type/expr-empty-ret.rs
new file mode 100644 (file)
index 0000000..ce8ffaf
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(dead_code)]
+// Issue #521
+
+// pretty-expanded FIXME #23616
+
+fn f() {
+    let _x = match true {
+        true => { 10 }
+        false => { return }
+    };
+}
+
+pub fn main() { }
index 67115a5ccdd4505738faecf3c1bf0e9f39b8124c..c9324f0422cdc4444d88921cff84884071898e92 100644 (file)
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
 LL |        let x = (vec![22], vec![44]);
    |            - captured outer variable
 LL |        expect_fn(|| drop(x.0));
-   |                          ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |                  --------^^^-
+   |                  |       |
+   |                  |       move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |                  captured by this `Fn` closure
 
 error: aborting due to previous error
 
index f8be5e76f7a1443b80c06c9f0bfac754ae1d3b5b..ce25da559da3faef9fd6e4d90f6c95722aa8c7c0 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
   --> $DIR/no_send-rc.rs:7:9
    |
 LL |     bar(x);
-   |         ^ `Rc<{integer}>` cannot be sent between threads safely
+   |     --- ^ `Rc<{integer}>` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Rc<{integer}>`
 note: required by a bound in `bar`
index 2f8cf3569aeeed5c286d4f6bbe62bfcb26e62611..ee7bdf282b740122a7cb3a194c56c03c81518479 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `Foo` cannot be sent between threads safely
   --> $DIR/no_send-struct.rs:15:9
    |
 LL |     bar(x);
-   |         ^ `Foo` cannot be sent between threads safely
+   |     --- ^ `Foo` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Foo`
 note: required by a bound in `bar`
index 8983b0867898ad6e348889933b5dd25ab95107c1..9ce3a318f1d3ba22e2329c9dd621c6339297c601 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `Foo` cannot be shared between threads safely
   --> $DIR/no_share-struct.rs:12:9
    |
 LL |     bar(x);
-   |         ^ `Foo` cannot be shared between threads safely
+   |     --- ^ `Foo` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `Foo`
 note: required by a bound in `bar`
index bf1641167cf1184de4ee5fc1001746a1ae5e222f..f1dd508a4674163c32e8ec6783793c62fd891db5 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Box<dyn Foo>: Foo` is not satisfied
   --> $DIR/object-does-not-impl-trait.rs:6:44
    |
 LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
-   |                                            ^ the trait `Foo` is not implemented for `Box<dyn Foo>`
+   |                                   -------- ^ the trait `Foo` is not implemented for `Box<dyn Foo>`
+   |                                   |
+   |                                   required by a bound introduced by this call
    |
 note: required by a bound in `take_foo`
   --> $DIR/object-does-not-impl-trait.rs:5:15
index 35ec586892c05b13e2934aba8465dfee635f9a2e..9dd144fee24a68550116fb5ebf82292c0cc3607b 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `X` to another trait
 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/object-safety-associated-consts.rs:9:11
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     const X: usize;
    |           ^ ...because it contains this associated `const`
+   = help: consider moving `X` to another trait
 
 error: aborting due to previous error
 
index d51734ed2316bbf1627a665e82fd338801617f28..9ba3b251e66034d207640e2cadd95609a8c6f07c 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     t
    |     ^ `Bar` cannot be made into an object
    |
-   = help: consider moving `X` to another trait
 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/object-safety-associated-consts.rs:9:11
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     const X: usize;
    |           ^ ...because it contains this associated `const`
+   = help: consider moving `X` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
index 8d6094c5144290c68ca2bc0def7f61368b4fa25f..345950f1ae670cb473598f10e32a51c4d7d09d94 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-generics.rs:10:8
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:24:39
@@ -19,7 +19,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
    |                                       ^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-generics.rs:10:8
    |
@@ -27,6 +26,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
 
 error: aborting due to 2 previous errors
 
index 3d2b2bb228cb529395c185dc71bbaf897a77d2ea..86355627c796f9040d82f9c48686c4518f2771a8 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     t
    |     ^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-generics.rs:10:8
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
@@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     t as &dyn Bar
    |     ^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-generics.rs:10:8
    |
@@ -29,6 +28,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
+   = help: consider moving `bar` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
index 336929702e6cd3d032a9f24efa3cbd7356df1d41..f91c9b9856055778e20bbf4ae4d39fa5f1fe1caf 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-mentions-Self.rs:11:22
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar(&self, x: &Self);
    |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
+   = help: consider moving `bar` to another trait
 
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:28:30
@@ -19,7 +19,6 @@ error[E0038]: the trait `Baz` cannot be made into an object
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    |                              ^^^^^^^^ `Baz` cannot be made into an object
    |
-   = help: consider moving `baz` to another trait
 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/object-safety-mentions-Self.rs:15:22
    |
@@ -27,6 +26,7 @@ LL | trait Baz {
    |       --- this trait cannot be made into an object...
 LL |     fn baz(&self) -> Self;
    |                      ^^^^ ...because method `baz` references the `Self` type in its return type
+   = help: consider moving `baz` to another trait
 
 error: aborting due to 2 previous errors
 
index 6e7896e309cc691ec9b20182800625b587f2e29a..f48628c9d1111fd24e5d847bb4b6855f6075cfa7 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
 LL |     t
    |     ^ `Bar` cannot be made into an object
    |
-   = help: consider moving `bar` to another trait
 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/object-safety-mentions-Self.rs:11:22
    |
@@ -12,6 +11,7 @@ LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar(&self, x: &Self);
    |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
+   = help: consider moving `bar` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
@@ -21,7 +21,6 @@ error[E0038]: the trait `Baz` cannot be made into an object
 LL |     t
    |     ^ `Baz` cannot be made into an object
    |
-   = help: consider moving `baz` to another trait
 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/object-safety-mentions-Self.rs:15:22
    |
@@ -29,6 +28,7 @@ LL | trait Baz {
    |       --- this trait cannot be made into an object...
 LL |     fn baz(&self) -> Self;
    |                      ^^^^ ...because method `baz` references the `Self` type in its return type
+   = help: consider moving `baz` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T`
    = note: required by cast to type `&dyn Baz`
 
index abd156dd5ac4a74198a82f6c5c94c2773c836066..67759d02a161e83db474b5275ba1ac167bee02b8 100644 (file)
@@ -4,7 +4,9 @@ error[E0277]: the trait bound `Foo: Trait` is not satisfied
 LL |       let x = || {
    |  _____________-
 LL | |         f(Foo{});
-   | |           ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |         - ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |         |
+   | |         required by a bound introduced by this call
 LL | |         let y = || {
 LL | |             f(Foo{});
 LL | |         };
@@ -23,7 +25,9 @@ error[E0277]: the trait bound `Foo: Trait` is not satisfied
 LL |           let y = || {
    |  _________________-
 LL | |             f(Foo{});
-   | |               ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |             - ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |             |
+   | |             required by a bound introduced by this call
 LL | |         };
    | |_________- in this scope
    |
@@ -42,7 +46,9 @@ LL | |         f(Foo{});
 LL | |         let y = || {
 ...  |
 LL | |             f(Foo{});
-   | |               ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |             - ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |             |
+   | |             required by a bound introduced by this call
 ...  |
 LL | |     f(Foo{});
 LL | | }
@@ -63,7 +69,9 @@ LL | |         f(Foo{});
 LL | |         let y = || {
 ...  |
 LL | |     f(Foo{});
-   | |       ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |     - ^^^^^ the trait `Trait` is not implemented for `Foo`
+   | |     |
+   | |     required by a bound introduced by this call
 LL | | }
    | |_- in this scope
    |
index 804b6282202be85cd9082d4bab3c18233cbcca47..a3658f224260633b69b14b9503596b588fb49a56 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:18
    |
 LL |     Index::index(&[] as &[i32], 2u32);
-   |                  ^^^^^^^^^^^^^ trait message
+   |     ------------ ^^^^^^^^^^^^^ trait message
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
 note: required by `Index::index`
@@ -15,7 +17,9 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:18
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |                  ^^^^^^^^^^^^^ on impl for Foo
+   |     ------------ ^^^^^^^^^^^^^ on impl for Foo
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
 note: required by `Index::index`
@@ -28,7 +32,9 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:18
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |                  ^^^^^^^^^^^^^ on impl for Bar
+   |     ------------ ^^^^^^^^^^^^^ on impl for Bar
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
 note: required by `Index::index`
index bfd438e5cc215212efa3983cd252901ce12a56fc..18eca06ba698111d36a1b8c1b6424b23a7127eef 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:25
    |
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |                         ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |     ------------------- ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
 note: required by `Index::index`
diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/out-of-order-shadowing.rs
deleted file mode 100644 (file)
index a0d1a97..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// aux-build:define-macro.rs
-
-macro_rules! bar { () => {} }
-define_macro!(bar);
-bar!(); //~ ERROR `bar` is ambiguous
-
-macro_rules! m { () => { #[macro_use] extern crate define_macro; } }
-m!();
-
-fn main() {}
diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr
deleted file mode 100644 (file)
index 1db31e0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0659]: `bar` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/out-of-order-shadowing.rs:5:1
-   |
-LL | bar!();
-   | ^^^ ambiguous name
-   |
-note: `bar` could refer to the macro defined here
-  --> $DIR/out-of-order-shadowing.rs:4:1
-   |
-LL | define_macro!(bar);
-   | ^^^^^^^^^^^^^^^^^^^
-note: `bar` could also refer to the macro defined here
-  --> $DIR/out-of-order-shadowing.rs:3:1
-   |
-LL | macro_rules! bar { () => {} }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this error originates in the macro `define_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0659`.
index 83bbf884a4ff8da4a617e80022ad1bc4df62af65..a5b7e83a016223848f319673aea1dacefdf8ce17 100644 (file)
@@ -1,10 +1,10 @@
 macro_rules! foo {
     ($rest: tt) => {
-        bar(baz: $rest)
+        bar(baz: $rest) //~ ERROR invalid `struct` delimiters or `fn` call arguments
     }
 }
 
 fn main() {
-    foo!(true); //~ ERROR expected type, found keyword
+    foo!(true);
     //~^ ERROR expected identifier, found keyword
 }
index 372387131e54b5c0c05ace1a17b67150846d526b..862026408ef7f8d9db8a9631a37f9b2f98c70f4e 100644 (file)
@@ -9,17 +9,25 @@ help: you can escape reserved keywords to use them as identifiers
 LL |     foo!(r#true);
    |          ~~~~~~
 
-error: expected type, found keyword `true`
-  --> $DIR/issue-44406.rs:8:10
+error: invalid `struct` delimiters or `fn` call arguments
+  --> $DIR/issue-44406.rs:3:9
    |
 LL |         bar(baz: $rest)
-   |                - help: try using a semicolon: `;`
+   |         ^^^^^^^^^^^^^^^
 ...
 LL |     foo!(true);
-   |          ^^^^ expected type
+   |     ----------- in this macro invocation
+   |
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: if `bar` is a struct, use braces as delimiters
+   |
+LL |         bar {  }
+   |             ~
+help: if `bar` is a function, use the arguments directly
    |
-   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+LL -         bar(baz: $rest)
+LL +         bar(true);
+   | 
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/issue-88583-union-as-ident.rs b/src/test/ui/parser/issue-88583-union-as-ident.rs
new file mode 100644 (file)
index 0000000..b3d66d4
--- /dev/null
@@ -0,0 +1,15 @@
+// check-pass
+
+#![allow(non_camel_case_types)]
+
+struct union;
+
+impl union {
+    pub fn new() -> Self {
+        union { }
+    }
+}
+
+fn main() {
+    let _u = union::new();
+}
diff --git a/src/test/ui/parser/issue-88818.rs b/src/test/ui/parser/issue-88818.rs
new file mode 100644 (file)
index 0000000..b9233ca
--- /dev/null
@@ -0,0 +1,10 @@
+// Regression test for #88818 (improve error message for missing trait
+// in `impl for X`).
+
+struct S { }
+impl for S { }
+//~^ ERROR: missing trait in a trait impl
+//~| HELP: add a trait here
+//~| HELP: for an inherent impl, drop this `for`
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-88818.stderr b/src/test/ui/parser/issue-88818.stderr
new file mode 100644 (file)
index 0000000..d30990a
--- /dev/null
@@ -0,0 +1,18 @@
+error: missing trait in a trait impl
+  --> $DIR/issue-88818.rs:5:5
+   |
+LL | impl for S { }
+   |     ^
+   |
+help: add a trait here
+   |
+LL | impl Trait for S { }
+   |      +++++
+help: for an inherent impl, drop this `for`
+   |
+LL - impl for S { }
+LL + impl S { }
+   | 
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro-braces-dot-question.rs b/src/test/ui/parser/macro-braces-dot-question.rs
new file mode 100644 (file)
index 0000000..016b434
--- /dev/null
@@ -0,0 +1,11 @@
+// check-pass
+
+use std::io::Write;
+
+fn main() -> Result<(), std::io::Error> {
+    vec! { 1, 2, 3 }.len();
+    write! { vec![], "" }?;
+    println!{""}
+    [0]; // separate statement, not indexing into the result of println.
+    Ok(())
+}
index 779e1646344787b680be00576c3e9d588791201d..8080dbc332ae7146d13648157bc3e64fde3f2f77 100644 (file)
@@ -9,7 +9,7 @@ fn main() {
 
     for ( elem in vec ) {
         //~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in`
-        //~| ERROR unexpected closing `)`
+        //~| ERROR unexpected parenthesis surrounding `for` loop head
         const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
     }
 }
index e97cf544ac2683d3df171e902c96ce71f753dfad..21991348327b36e99d5f4c67b9aa5e2057b91a91 100644 (file)
@@ -4,14 +4,17 @@ error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
 LL |     for ( elem in vec ) {
    |                ^^ expected one of `)`, `,`, `@`, or `|`
 
-error: unexpected closing `)`
-  --> $DIR/recover-for-loop-parens-around-head.rs:10:23
+error: unexpected parenthesis surrounding `for` loop head
+  --> $DIR/recover-for-loop-parens-around-head.rs:10:9
    |
 LL |     for ( elem in vec ) {
-   |         --------------^
-   |         |
-   |         opening `(`
-   |         help: remove parenthesis in `for` loop: `elem in vec`
+   |         ^             ^
+   |
+help: remove parenthesis in `for` loop
+   |
+LL -     for ( elem in vec ) {
+LL +     for  elem in vec  {
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/recover-for-loop-parens-around-head.rs:13:38
index 1bcef450bb9be4706477d6367ec7cb91c7da1058..e8887147cbc863a9debfa7ac8b91547874034b16 100644 (file)
@@ -5,7 +5,7 @@ enum Enum {
 
 fn main() {
     let x = Enum::Foo(a: 3, b: 4);
-    //~^ ERROR expected type, found `3`
+    //~^ ERROR invalid `struct` delimiters or `fn` call arguments
     match x {
         Enum::Foo(a, b) => {}
         //~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo`
index 61ea3695eee0b1adc4960b7705553393442ddab8..8cb71069bdaaca5f3c08eaf17b521e68bc255d7f 100644 (file)
@@ -1,13 +1,18 @@
-error: expected type, found `3`
-  --> $DIR/recover-from-bad-variant.rs:7:26
+error: invalid `struct` delimiters or `fn` call arguments
+  --> $DIR/recover-from-bad-variant.rs:7:13
    |
 LL |     let x = Enum::Foo(a: 3, b: 4);
-   |                        - ^ expected type
-   |                        |
-   |                        tried to parse a type due to this type ascription
+   |             ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+help: if `Enum::Foo` is a struct, use braces as delimiters
+   |
+LL |     let x = Enum::Foo { a: 3, b: 4 };
+   |                       ~            ~
+help: if `Enum::Foo` is a function, use the arguments directly
+   |
+LL -     let x = Enum::Foo(a: 3, b: 4);
+LL +     let x = Enum::Foo(3, 4);
+   | 
 
 error[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo`
   --> $DIR/recover-from-bad-variant.rs:10:9
index e7b5528daee920d48cd64e97bebb67751be27d9b..1cc653c51cfa1244b46ebeca5f7a71b678c648a6 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-auto-trait.rs:21:12
    |
 LL |     is_zen(x)
-   |            ^ `T` cannot be shared between threads safely
+   |     ------ ^ `T` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Zen` for `&T`
   --> $DIR/phantom-auto-trait.rs:10:24
@@ -29,7 +31,9 @@ error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-auto-trait.rs:26:12
    |
 LL |     is_zen(x)
-   |            ^ `T` cannot be shared between threads safely
+   |     ------ ^ `T` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because of the requirements on the impl of `Zen` for `&T`
   --> $DIR/phantom-auto-trait.rs:10:24
diff --git a/src/test/ui/polymorphization/issue-74614.rs b/src/test/ui/polymorphization/issue-74614.rs
new file mode 100644 (file)
index 0000000..8b0c00b
--- /dev/null
@@ -0,0 +1,18 @@
+// compile-flags:-Zpolymorphize=on
+// build-pass
+
+fn test<T>() {
+    std::mem::size_of::<T>();
+}
+
+pub fn foo<T>(_: T) -> &'static fn() {
+    &(test::<T> as fn())
+}
+
+fn outer<T>() {
+    foo(|| ());
+}
+
+fn main() {
+    outer::<u8>();
+}
diff --git a/src/test/ui/privacy/issue-79593.rs b/src/test/ui/privacy/issue-79593.rs
new file mode 100644 (file)
index 0000000..b94278b
--- /dev/null
@@ -0,0 +1,29 @@
+mod foo {
+    pub struct Pub { private: () }
+
+    pub enum Enum {
+        Variant { x: (), y: () },
+        Other
+    }
+
+    fn correct() {
+        Pub {};
+        //~^ ERROR missing field `private` in initializer of `Pub`
+        Enum::Variant { x: () };
+        //~^ ERROR missing field `y` in initializer of `Enum`
+    }
+}
+
+fn correct() {
+    foo::Pub {};
+    //~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields
+}
+
+fn wrong() {
+    foo::Enum::Variant { x: () };
+    //~^ ERROR missing field `y` in initializer of `Enum`
+    foo::Enum::Variant { };
+    //~^ ERROR missing fields `x` and `y` in initializer of `Enum`
+}
+
+fn main() {}
diff --git a/src/test/ui/privacy/issue-79593.stderr b/src/test/ui/privacy/issue-79593.stderr
new file mode 100644 (file)
index 0000000..b8c7d4f
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0063]: missing field `private` in initializer of `Pub`
+  --> $DIR/issue-79593.rs:10:9
+   |
+LL |         Pub {};
+   |         ^^^ missing `private`
+
+error[E0063]: missing field `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:12:9
+   |
+LL |         Enum::Variant { x: () };
+   |         ^^^^^^^^^^^^^ missing `y`
+
+error: cannot construct `Pub` with struct literal syntax due to inaccessible fields
+  --> $DIR/issue-79593.rs:18:5
+   |
+LL |     foo::Pub {};
+   |     ^^^^^^^^
+
+error[E0063]: missing field `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:23:5
+   |
+LL |     foo::Enum::Variant { x: () };
+   |     ^^^^^^^^^^^^^^^^^^ missing `y`
+
+error[E0063]: missing fields `x` and `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:25:5
+   |
+LL |     foo::Enum::Variant { };
+   |     ^^^^^^^^^^^^^^^^^^ missing `x` and `y`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/repr/repr-transparent-issue-87496.rs b/src/test/ui/repr/repr-transparent-issue-87496.rs
new file mode 100644 (file)
index 0000000..a4dd45c
--- /dev/null
@@ -0,0 +1,12 @@
+// Regression test for the ICE described in #87496.
+
+// check-pass
+
+#[repr(transparent)]
+struct TransparentCustomZst(());
+extern "C" {
+    fn good17(p: TransparentCustomZst);
+    //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
+}
+
+fn main() {}
diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr
new file mode 100644 (file)
index 0000000..c488755
--- /dev/null
@@ -0,0 +1,16 @@
+warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
+  --> $DIR/repr-transparent-issue-87496.rs:8:18
+   |
+LL |     fn good17(p: TransparentCustomZst);
+   |                  ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: `#[warn(improper_ctypes)]` on by default
+   = note: this struct contains only zero-sized fields
+note: the type is defined here
+  --> $DIR/repr-transparent-issue-87496.rs:6:1
+   |
+LL | struct TransparentCustomZst(());
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/resolve/issue-42944.rs b/src/test/ui/resolve/issue-42944.rs
new file mode 100644 (file)
index 0000000..a440485
--- /dev/null
@@ -0,0 +1,21 @@
+mod foo {
+    pub struct Bx(());
+}
+
+mod bar {
+    use foo::Bx;
+
+    fn foo() {
+        Bx(());
+        //~^ ERROR cannot initialize a tuple struct which contains private fields [E0423]
+    }
+}
+
+mod baz {
+    fn foo() {
+        Bx(());
+        //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` in this scope [E0425]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-42944.stderr b/src/test/ui/resolve/issue-42944.stderr
new file mode 100644 (file)
index 0000000..0084925
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/issue-42944.rs:9:9
+   |
+LL |         Bx(());
+   |         ^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/issue-42944.rs:2:19
+   |
+LL |     pub struct Bx(());
+   |                   ^^ private field
+
+error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this scope
+  --> $DIR/issue-42944.rs:16:9
+   |
+LL |         Bx(());
+   |         ^^ not found in this scope
+   |
+help: consider importing this tuple struct
+   |
+LL |     use foo::Bx;
+   |
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0425.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/resolve/use-self-in-inner-fn.rs b/src/test/ui/resolve/use-self-in-inner-fn.rs
new file mode 100644 (file)
index 0000000..eccb315
--- /dev/null
@@ -0,0 +1,14 @@
+struct A;
+
+impl A {
+//~^ NOTE `Self` type implicitly declared here, by this `impl`
+    fn banana(&mut self) {
+        fn peach(this: &Self) {
+        //~^ ERROR can't use generic parameters from outer function
+        //~| NOTE use of generic parameter from outer function
+        //~| NOTE use a type here instead
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/use-self-in-inner-fn.stderr b/src/test/ui/resolve/use-self-in-inner-fn.stderr
new file mode 100644 (file)
index 0000000..9660934
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/use-self-in-inner-fn.rs:6:25
+   |
+LL | impl A {
+   | ---- `Self` type implicitly declared here, by this `impl`
+...
+LL |         fn peach(this: &Self) {
+   |                         ^^^^
+   |                         |
+   |                         use of generic parameter from outer function
+   |                         use a type here instead
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0401`.
index 8516bafef9bd9e9f45f03e5cb34da55bc92fd71e..0098f087d10f8dcf469d7d45683beb8683c871dd 100644 (file)
@@ -4,8 +4,29 @@
 pub enum NonExhaustiveEnum {
     Unit,
     Tuple(u32),
-    Struct { field: u32 }
+    Struct { field: u32 },
+}
+
+#[non_exhaustive]
+pub enum NestedNonExhaustive {
+    A(NonExhaustiveEnum),
+    B,
+    C,
 }
 
 #[non_exhaustive]
 pub enum EmptyNonExhaustiveEnum {}
+
+pub enum VariantNonExhaustive {
+    #[non_exhaustive]
+    Bar {
+        x: u32,
+        y: u64,
+    },
+    Baz(u32, u16),
+}
+
+#[non_exhaustive]
+pub enum NonExhaustiveSingleVariant {
+    A(bool),
+}
index 6bfe7bf923d0901e2cf5ddb92d31d86fc89d4604..5b2181d2d833b120688d2390e3cc3452b634b94b 100644 (file)
@@ -1,3 +1,4 @@
+#[derive(Default)]
 #[non_exhaustive]
 pub struct NormalStruct {
     pub first_field: u16,
@@ -15,7 +16,7 @@ pub struct NormalStruct {
 pub struct FunctionalRecord {
     pub first_field: u16,
     pub second_field: u16,
-    pub third_field: bool
+    pub third_field: bool,
 }
 
 impl Default for FunctionalRecord {
@@ -23,3 +24,10 @@ fn default() -> FunctionalRecord {
         FunctionalRecord { first_field: 640, second_field: 480, third_field: false }
     }
 }
+
+#[derive(Default)]
+#[non_exhaustive]
+pub struct NestedStruct {
+    pub foo: u16,
+    pub bar: NormalStruct,
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
new file mode 100644 (file)
index 0000000..115fd30
--- /dev/null
@@ -0,0 +1,160 @@
+// Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
+
+// aux-build:enums.rs
+extern crate enums;
+
+// aux-build:structs.rs
+extern crate structs;
+
+use enums::{
+    EmptyNonExhaustiveEnum, NestedNonExhaustive, NonExhaustiveEnum, NonExhaustiveSingleVariant,
+    VariantNonExhaustive,
+};
+use structs::{FunctionalRecord, NestedStruct, NormalStruct};
+
+#[non_exhaustive]
+#[derive(Default)]
+pub struct Foo {
+    a: u8,
+    b: usize,
+    c: String,
+}
+
+#[non_exhaustive]
+pub enum Bar {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    let enumeration = Bar::A;
+
+    // Ok: this is a crate local non_exhaustive enum
+    match enumeration {
+        Bar::A => {}
+        Bar::B => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+
+    let non_enum = NonExhaustiveEnum::Unit;
+
+    // Ok: without the attribute
+    match non_enum {
+        NonExhaustiveEnum::Unit => {}
+        NonExhaustiveEnum::Tuple(_) => {}
+        _ => {}
+    }
+
+    match non_enum {
+        NonExhaustiveEnum::Unit => {}
+        NonExhaustiveEnum::Tuple(_) => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    match non_enum {
+        NonExhaustiveEnum::Unit | NonExhaustiveEnum::Struct { .. } => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    let x = 5;
+    match non_enum {
+        NonExhaustiveEnum::Unit if x > 10 => {}
+        NonExhaustiveEnum::Tuple(_) => {}
+        NonExhaustiveEnum::Struct { .. } => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    // Ok: all covered and not `unreachable-patterns`
+    #[deny(unreachable_patterns)]
+    match non_enum {
+        NonExhaustiveEnum::Unit => {}
+        NonExhaustiveEnum::Tuple(_) => {}
+        NonExhaustiveEnum::Struct { .. } => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+
+    #[deny(non_exhaustive_omitted_patterns)]
+    match NestedNonExhaustive::B {
+        NestedNonExhaustive::A(NonExhaustiveEnum::Unit) => {}
+        NestedNonExhaustive::A(_) => {}
+        NestedNonExhaustive::B => {}
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+    //~^^^^^ some variants are not matched explicitly
+
+    // The io::ErrorKind has many `unstable` fields how do they interact with this
+    // lint
+    #[deny(non_exhaustive_omitted_patterns)]
+    match std::io::ErrorKind::Other {
+        std::io::ErrorKind::NotFound => {}
+        std::io::ErrorKind::PermissionDenied => {}
+        std::io::ErrorKind::ConnectionRefused => {}
+        std::io::ErrorKind::ConnectionReset => {}
+        std::io::ErrorKind::ConnectionAborted => {}
+        std::io::ErrorKind::NotConnected => {}
+        std::io::ErrorKind::AddrInUse => {}
+        std::io::ErrorKind::AddrNotAvailable => {}
+        std::io::ErrorKind::BrokenPipe => {}
+        std::io::ErrorKind::AlreadyExists => {}
+        std::io::ErrorKind::WouldBlock => {}
+        std::io::ErrorKind::InvalidInput => {}
+        std::io::ErrorKind::InvalidData => {}
+        std::io::ErrorKind::TimedOut => {}
+        std::io::ErrorKind::WriteZero => {}
+        std::io::ErrorKind::Interrupted => {}
+        std::io::ErrorKind::Other => {}
+        std::io::ErrorKind::UnexpectedEof => {}
+        std::io::ErrorKind::Unsupported => {}
+        std::io::ErrorKind::OutOfMemory => {}
+        // All stable variants are above and unstable in `_`
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    match VariantNonExhaustive::Baz(1, 2) {
+        VariantNonExhaustive::Baz(_, _) => {}
+        VariantNonExhaustive::Bar { x, .. } => {}
+    }
+    //~^^ some fields are not explicitly listed
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
+    //~^ some fields are not explicitly listed
+
+    // Ok: this is local
+    #[warn(non_exhaustive_omitted_patterns)]
+    let Foo { a, b, .. } = Foo::default();
+
+    #[warn(non_exhaustive_omitted_patterns)]
+    let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
+    //~^ some fields are not explicitly listed
+    //~^^ some fields are not explicitly listed
+
+    // Ok: because this only has 1 variant
+    #[deny(non_exhaustive_omitted_patterns)]
+    match NonExhaustiveSingleVariant::A(true) {
+        NonExhaustiveSingleVariant::A(true) => {}
+        _ => {}
+    }
+
+    #[deny(non_exhaustive_omitted_patterns)]
+    match NonExhaustiveSingleVariant::A(true) {
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    // Ok: we don't lint on `if let` expressions
+    #[deny(non_exhaustive_omitted_patterns)]
+    if let NonExhaustiveEnum::Tuple(_) = non_enum {}
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
new file mode 100644 (file)
index 0000000..aebe2ac
--- /dev/null
@@ -0,0 +1,146 @@
+warning: some fields are not explicitly listed
+  --> $DIR/reachable-patterns.rs:127:9
+   |
+LL |         VariantNonExhaustive::Bar { x, .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:124:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
+
+warning: some fields are not explicitly listed
+  --> $DIR/reachable-patterns.rs:132:9
+   |
+LL |     let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:131:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
+
+warning: some fields are not explicitly listed
+  --> $DIR/reachable-patterns.rs:140:29
+   |
+LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:139:12
+   |
+LL |     #[warn(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
+
+warning: some fields are not explicitly listed
+  --> $DIR/reachable-patterns.rs:140:9
+   |
+LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed
+   |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:54:9
+   |
+LL |         _ => {}
+   |         ^ pattern `Struct { .. }` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:53:16
+   |
+LL |         #[deny(non_exhaustive_omitted_patterns)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:61:9
+   |
+LL |         _ => {}
+   |         ^ pattern `Tuple(_)` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:60:16
+   |
+LL |         #[deny(non_exhaustive_omitted_patterns)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:71:9
+   |
+LL |         _ => {}
+   |         ^ pattern `Unit` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:70:16
+   |
+LL |         #[deny(non_exhaustive_omitted_patterns)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:88:32
+   |
+LL |         NestedNonExhaustive::A(_) => {}
+   |                                ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:85:12
+   |
+LL |     #[deny(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:90:9
+   |
+LL |         _ => {}
+   |         ^ pattern `C` not covered
+   |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:120:9
+   |
+LL |         _ => {}
+   |         ^ patterns `HostUnreachable`, `NetworkUnreachable`, `NetworkDown` and 18 more not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:97:12
+   |
+LL |     #[deny(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/reachable-patterns.rs:153:9
+   |
+LL |         _ => {}
+   |         ^ pattern `A(_)` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/reachable-patterns.rs:151:12
+   |
+LL |     #[deny(non_exhaustive_omitted_patterns)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: aborting due to 7 previous errors; 4 warnings emitted
+
index b0c319f2c7f4188be632036d70463296597125d6..272b2ef6ee1d1c33e4ca036e16264c4805f795a5 100644 (file)
@@ -16,13 +16,13 @@ error[E0603]: tuple struct constructor `TupleStruct` is private
 LL |     let ts_explicit = structs::TupleStruct(640, 480);
    |                                ^^^^^^^^^^^ private tuple struct constructor
    |
-  ::: $DIR/auxiliary/structs.rs:11:24
+  ::: $DIR/auxiliary/structs.rs:12:24
    |
 LL | pub struct TupleStruct(pub u16, pub u16);
    |                        ---------------- a constructor is private if any of the fields is private
    |
 note: the tuple struct constructor `TupleStruct` is defined here
-  --> $DIR/auxiliary/structs.rs:11:1
+  --> $DIR/auxiliary/structs.rs:12:1
    |
 LL | pub struct TupleStruct(pub u16, pub u16);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL |     let us_explicit = structs::UnitStruct;
    |                                ^^^^^^^^^^ private unit struct
    |
 note: the unit struct `UnitStruct` is defined here
-  --> $DIR/auxiliary/structs.rs:8:1
+  --> $DIR/auxiliary/structs.rs:9:1
    |
 LL | pub struct UnitStruct;
    | ^^^^^^^^^^^^^^^^^^^^^^
index 7185376b440c8fdf10e7b029f7f94f2a4ac1acba..cc24dbd96d2532ebc82c59a2e9fc4a7514891d86 100644 (file)
@@ -16,12 +16,17 @@ fn ne(&self, other: &S) -> bool {
 
 // This duplicate bound should not result in ambiguities. It should be equivalent to a single ~const
 // bound.
-// const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
-// FIXME(fee1-dead)^ why should the order matter here?
-const fn equals_self<T: ~const PartialEq + PartialEq>(t: &T) -> bool {
+const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
     *t == *t
 }
 
-pub const EQ: bool = equals_self(&S);
+trait A: PartialEq {}
+impl<T: PartialEq> A for T {}
+
+const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+pub const EQ: bool = equals_self(&S) && equals_self2(&S);
 
 fn main() {}
index 9b9bda7c90ec7d313aab8b9096411c4c5d6acc2f..0440f17a704deb18f88300aa614dd0c9d027240f 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: can't compare `S` with `S`
   --> $DIR/call-generic-method-nonconst.rs:19:34
    |
 LL | pub const EQ: bool = equals_self(&S);
-   |                                  ^^ no implementation for `S == S`
+   |                      ----------- ^^ no implementation for `S == S`
+   |                      |
+   |                      required by a bound introduced by this call
    |
    = help: the trait `PartialEq` is not implemented for `S`
 note: required by a bound in `equals_self`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
new file mode 100644 (file)
index 0000000..34cd1d2
--- /dev/null
@@ -0,0 +1,68 @@
+error: `~const` is not allowed here
+  --> $DIR/const-drop-fail.rs:27:35
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   |                                   ^^^^^^^^
+   |
+   = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
+
+error[E0277]: the trait bound `NonTrivialDrop: Drop` is not satisfied
+  --> $DIR/const-drop-fail.rs:45:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     NonTrivialDrop,
+   |     ^^^^^^^^^^^^^^ the trait `Drop` is not implemented for `NonTrivialDrop`
+   |
+note: required by a bound in `check`
+  --> $DIR/const-drop-fail.rs:36:19
+   |
+LL | const fn check<T: ~const Drop>(_: T) {}
+   |                   ^^^^^^^^^^^ required by this bound in `check`
+
+error[E0277]: the trait bound `ConstImplWithDropGlue: Drop` is not satisfied
+  --> $DIR/const-drop-fail.rs:47:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     ConstImplWithDropGlue(NonTrivialDrop),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Drop` is not implemented for `ConstImplWithDropGlue`
+   |
+note: required by a bound in `check`
+  --> $DIR/const-drop-fail.rs:36:19
+   |
+LL | const fn check<T: ~const Drop>(_: T) {}
+   |                   ^^^^^^^^^^^ required by this bound in `check`
+
+error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied
+  --> $DIR/const-drop-fail.rs:49:5
+   |
+LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop`
+   |
+note: required by `ConstDropImplWithBounds`
+  --> $DIR/const-drop-fail.rs:27:1
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied
+  --> $DIR/const-drop-fail.rs:49:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop`
+   |
+note: required by a bound in `ConstDropImplWithBounds`
+  --> $DIR/const-drop-fail.rs:27:35
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   |                                   ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
new file mode 100644 (file)
index 0000000..3d4de08
--- /dev/null
@@ -0,0 +1,54 @@
+// revisions: stock precise
+#![feature(const_trait_impl)]
+#![feature(const_mut_refs)]
+#![feature(const_fn_trait_bound)]
+#![cfg_attr(precise, feature(const_precise_live_drops))]
+
+use std::marker::PhantomData;
+
+struct NonTrivialDrop;
+
+impl Drop for NonTrivialDrop {
+    fn drop(&mut self) {
+        println!("Non trivial drop");
+    }
+}
+
+struct ConstImplWithDropGlue(NonTrivialDrop);
+
+impl const Drop for ConstImplWithDropGlue {
+    fn drop(&mut self) {}
+}
+
+trait A { fn a() { println!("A"); } }
+
+impl A for NonTrivialDrop {}
+
+struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+//~^ ERROR `~const` is not allowed
+
+impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
+    fn drop(&mut self) {
+        T::a();
+    }
+}
+
+const fn check<T: ~const Drop>(_: T) {}
+
+macro_rules! check_all {
+    ($($exp:expr),*$(,)?) => {$(
+        const _: () = check($exp);
+    )*};
+}
+
+check_all! {
+    NonTrivialDrop,
+    //~^ ERROR the trait bound
+    ConstImplWithDropGlue(NonTrivialDrop),
+    //~^ ERROR the trait bound
+    ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
+    //~^ ERROR the trait bound
+    //~| ERROR the trait bound
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
new file mode 100644 (file)
index 0000000..34cd1d2
--- /dev/null
@@ -0,0 +1,68 @@
+error: `~const` is not allowed here
+  --> $DIR/const-drop-fail.rs:27:35
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   |                                   ^^^^^^^^
+   |
+   = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
+
+error[E0277]: the trait bound `NonTrivialDrop: Drop` is not satisfied
+  --> $DIR/const-drop-fail.rs:45:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     NonTrivialDrop,
+   |     ^^^^^^^^^^^^^^ the trait `Drop` is not implemented for `NonTrivialDrop`
+   |
+note: required by a bound in `check`
+  --> $DIR/const-drop-fail.rs:36:19
+   |
+LL | const fn check<T: ~const Drop>(_: T) {}
+   |                   ^^^^^^^^^^^ required by this bound in `check`
+
+error[E0277]: the trait bound `ConstImplWithDropGlue: Drop` is not satisfied
+  --> $DIR/const-drop-fail.rs:47:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     ConstImplWithDropGlue(NonTrivialDrop),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Drop` is not implemented for `ConstImplWithDropGlue`
+   |
+note: required by a bound in `check`
+  --> $DIR/const-drop-fail.rs:36:19
+   |
+LL | const fn check<T: ~const Drop>(_: T) {}
+   |                   ^^^^^^^^^^^ required by this bound in `check`
+
+error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied
+  --> $DIR/const-drop-fail.rs:49:5
+   |
+LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop`
+   |
+note: required by `ConstDropImplWithBounds`
+  --> $DIR/const-drop-fail.rs:27:1
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied
+  --> $DIR/const-drop-fail.rs:49:5
+   |
+LL |         const _: () = check($exp);
+   |                       ----- required by a bound introduced by this call
+...
+LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop`
+   |
+note: required by a bound in `ConstDropImplWithBounds`
+  --> $DIR/const-drop-fail.rs:27:35
+   |
+LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+   |                                   ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
new file mode 100644 (file)
index 0000000..9a1b554
--- /dev/null
@@ -0,0 +1,81 @@
+// run-pass
+// revisions: stock precise
+#![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)]
+#![feature(const_mut_refs)]
+#![feature(const_panic)]
+#![cfg_attr(precise, feature(const_precise_live_drops))]
+
+struct S<'a>(&'a mut u8);
+
+impl<'a> const Drop for S<'a> {
+    fn drop(&mut self) {
+        *self.0 += 1;
+    }
+}
+
+const fn a<T: ~const Drop>(_: T) {}
+
+const fn b() -> u8 {
+    let mut c = 0;
+    let _ = S(&mut c);
+    a(S(&mut c));
+    c
+}
+
+const C: u8 = b();
+
+macro_rules! implements_const_drop {
+    ($($exp:expr),*$(,)?) => {
+        $(
+            const _: () = a($exp);
+        )*
+    }
+}
+
+#[allow(dead_code)]
+mod t {
+    pub struct Foo;
+    pub enum Bar { A }
+    pub fn foo() {}
+    pub struct ConstDrop;
+
+    impl const Drop for ConstDrop {
+        fn drop(&mut self) {}
+    }
+
+    pub struct HasConstDrop(pub ConstDrop);
+    pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
+}
+
+use t::*;
+
+implements_const_drop! {
+    1u8,
+    2,
+    3.0,
+    Foo,
+    Bar::A,
+    foo,
+    ConstDrop,
+    HasConstDrop(ConstDrop),
+    TrivialFields(1, 2, 3, 4),
+    &1,
+    &1 as *const i32,
+}
+
+fn main() {
+    struct HasDropGlue(Box<u8>);
+    struct HasDropImpl;
+    impl Drop for HasDropImpl {
+        fn drop(&mut self) {
+            println!("not trivial drop");
+        }
+    }
+
+    // These types should pass because ~const in a non-const context should have no effect.
+    a(HasDropGlue(Box::new(0)));
+    a(HasDropImpl);
+
+    assert_eq!(C, 2);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs
new file mode 100644 (file)
index 0000000..fe1015b
--- /dev/null
@@ -0,0 +1,21 @@
+// check-pass
+#![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)]
+
+struct S;
+
+trait A {}
+trait B {}
+
+impl const A for S {}
+impl const B for S {}
+
+impl S {
+    const fn a<T: ~const A>() where T: ~const B {
+
+    }
+}
+
+const _: () = S::a::<S>();
+
+fn main() {}
index 81c0c4a78752313e925435f7632f8c2515d2d0f0..ea22d1c89b1cc38676067213af1b9f40dabbb0d0 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<()>` closure, found `fn() {foo}`
   --> $DIR/fn-traits.rs:24:10
    |
 LL |     call(foo);
-   |          ^^^ expected an `Fn<()>` closure, found `fn() {foo}`
+   |     ---- ^^^ expected an `Fn<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Fn<()>` is not implemented for `fn() {foo}`
    = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
@@ -17,7 +19,9 @@ error[E0277]: expected a `FnMut<()>` closure, found `fn() {foo}`
   --> $DIR/fn-traits.rs:25:14
    |
 LL |     call_mut(foo);
-   |              ^^^ expected an `FnMut<()>` closure, found `fn() {foo}`
+   |     -------- ^^^ expected an `FnMut<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `FnMut<()>` is not implemented for `fn() {foo}`
    = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
@@ -32,7 +36,9 @@ error[E0277]: expected a `FnOnce<()>` closure, found `fn() {foo}`
   --> $DIR/fn-traits.rs:26:15
    |
 LL |     call_once(foo);
-   |               ^^^ expected an `FnOnce<()>` closure, found `fn() {foo}`
+   |     --------- ^^^ expected an `FnOnce<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `FnOnce<()>` is not implemented for `fn() {foo}`
    = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
@@ -47,7 +53,9 @@ error[E0277]: expected a `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
   --> $DIR/fn-traits.rs:28:10
    |
 LL |     call(foo_unsafe);
-   |          ^^^^^^^^^^ expected an `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     ---- ^^^^^^^^^^ expected an `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Fn<()>` is not implemented for `unsafe fn() {foo_unsafe}`
    = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
@@ -62,7 +70,9 @@ error[E0277]: expected a `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
   --> $DIR/fn-traits.rs:30:14
    |
 LL |     call_mut(foo_unsafe);
-   |              ^^^^^^^^^^ expected an `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     -------- ^^^^^^^^^^ expected an `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `FnMut<()>` is not implemented for `unsafe fn() {foo_unsafe}`
    = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
@@ -77,7 +87,9 @@ error[E0277]: expected a `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
   --> $DIR/fn-traits.rs:32:15
    |
 LL |     call_once(foo_unsafe);
-   |               ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     --------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `FnOnce<()>` is not implemented for `unsafe fn() {foo_unsafe}`
    = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
index ab1fa2a4d87656b6702a1308258016f1d46cb5a6..0f630abd14876a5b21a0e00e40e1654270209403 100644 (file)
@@ -29,11 +29,17 @@ LL |     f.f.call_mut(())
 error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
    |
-LL |     let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
-   |         ----- captured outer variable
+LL |       let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+   |           ----- captured outer variable
 ...
-LL |         foo(f);
-   |             ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
+LL |       f(Box::new(|a| {
+   |  ________________-
+LL | |
+LL | |         foo(f);
+   | |             ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
+LL | |
+LL | |     }), 3);
+   | |_____- captured by this `FnMut` closure
 
 error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
diff --git a/src/test/ui/specialization/issue-35376.rs b/src/test/ui/specialization/issue-35376.rs
new file mode 100644 (file)
index 0000000..cc35213
--- /dev/null
@@ -0,0 +1,43 @@
+// check-pass
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+fn main() {}
+
+pub trait Alpha<T> { }
+
+pub trait Beta {
+    type Event;
+}
+
+pub trait Delta {
+    type Handle;
+    fn process(&self);
+}
+
+pub struct Parent<A, T>(A, T);
+
+impl<A, T> Delta for Parent<A, T>
+where A: Alpha<T::Handle>,
+      T: Delta,
+      T::Handle: Beta<Event = <Handle as Beta>::Event> {
+    type Handle = Handle;
+    default fn process(&self) {
+        unimplemented!()
+    }
+}
+
+impl<A, T> Delta for Parent<A, T>
+where A: Alpha<T::Handle> + Alpha<Handle>,
+      T: Delta,
+      T::Handle: Beta<Event = <Handle as Beta>::Event> {
+      fn process(&self) {
+        unimplemented!()
+      }
+}
+
+pub struct Handle;
+
+impl Beta for Handle {
+    type Event = ();
+}
diff --git a/src/test/ui/specialization/issue-35376.stderr b/src/test/ui/specialization/issue-35376.stderr
new file mode 100644 (file)
index 0000000..835277d
--- /dev/null
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-35376.rs:2:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/static/issue-34194.rs b/src/test/ui/static/issue-34194.rs
new file mode 100644 (file)
index 0000000..6dce556
--- /dev/null
@@ -0,0 +1,11 @@
+// build-pass
+#![allow(dead_code)]
+
+struct A {
+    a: &'static (),
+}
+
+static B: &'static A = &A { a: &() };
+static C: &'static A = &B;
+
+fn main() {}
index f323ba03c012cfd50753f64b43bd2b27fd72443d..47bd6f6bfa73d0158de9caf50e65c7c293f1fa15 100644 (file)
@@ -13,7 +13,9 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-idx.rs:4:19
    |
 LL |     let _ = s.get(4);
-   |                   ^ string indices are ranges of `usize`
+   |               --- ^ string indices are ranges of `usize`
+   |               |
+   |               required by a bound introduced by this call
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
@@ -23,7 +25,9 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-idx.rs:5:29
    |
 LL |     let _ = s.get_unchecked(4);
-   |                             ^ string indices are ranges of `usize`
+   |               ------------- ^ string indices are ranges of `usize`
+   |               |
+   |               required by a bound introduced by this call
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
index 3e49c8394ab0a06c4c685c0bdf2527428da3eb4b..ab647c75cf1205c88d919bf040775ff230c203a2 100644 (file)
@@ -37,7 +37,9 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-mut-idx.rs:9:15
    |
 LL |     s.get_mut(1);
-   |               ^ string indices are ranges of `usize`
+   |       ------- ^ string indices are ranges of `usize`
+   |       |
+   |       required by a bound introduced by this call
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
@@ -47,7 +49,9 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-mut-idx.rs:11:25
    |
 LL |     s.get_unchecked_mut(1);
-   |                         ^ string indices are ranges of `usize`
+   |       ----------------- ^ string indices are ranges of `usize`
+   |       |
+   |       required by a bound introduced by this call
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
diff --git a/src/test/ui/structs-enums/issue-38002.rs b/src/test/ui/structs-enums/issue-38002.rs
new file mode 100644 (file)
index 0000000..fdb31fc
--- /dev/null
@@ -0,0 +1,35 @@
+// run-pass
+#![allow(dead_code)]
+// Check that constant ADTs are codegened OK, part k of N.
+
+enum Bar {
+    C
+}
+
+enum Foo {
+    A {},
+    B {
+        y: usize,
+        z: Bar
+    },
+}
+
+const LIST: [(usize, Foo); 2] = [
+    (51, Foo::B { y: 42, z: Bar::C }),
+    (52, Foo::B { y: 45, z: Bar::C }),
+];
+
+pub fn main() {
+    match LIST {
+        [
+            (51, Foo::B { y: 42, z: Bar::C }),
+            (52, Foo::B { y: 45, z: Bar::C })
+        ] => {}
+        _ => {
+            // I would want to print the enum here, but if
+            // the discriminant is garbage this causes an
+            // `unreachable` and silent process exit.
+            panic!("trivial match failed")
+        }
+    }
+}
index 300c2a66c2996568af89bb03c6e33027ca839f46..78ebb3d6bfc245cebfe2b58aa8a040de58a158c4 100644 (file)
@@ -5,7 +5,9 @@ LL | async fn foo() {}
    |          --- consider calling this function
 ...
 LL |     bar(foo);
-   |         ^^^ `fn() -> impl Future {foo}` is not a future
+   |     --- ^^^ `fn() -> impl Future {foo}` is not a future
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Future` is not implemented for `fn() -> impl Future {foo}`
 note: required by a bound in `bar`
@@ -24,7 +26,9 @@ error[E0277]: `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-be
 LL |     let async_closure = async || ();
    |                         -------- consider calling this closure
 LL |     bar(async_closure);
-   |         ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]` is not a future
+   |     --- ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]` is not a future
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Future` is not implemented for `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]`
 note: required by a bound in `bar`
index c50cbcde85553f43743b419998318f1a51588ced..fb1055c9c30931f9d307d13fb77aec747ceb2ece 100644 (file)
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:28:21
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(_t) = x;
-   |               --    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+   | |               --    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL | |
+LL | |
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:32:34
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         if let Either::One(_t) = e { }
-   |                            --    ^ help: consider borrowing here: `&e`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+LL | |
+LL | |         if let Either::One(_t) = e { }
+   | |                            --    ^ help: consider borrowing here: `&e`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:36:37
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         while let Either::One(_t) = e { }
-   |                               --    ^ help: consider borrowing here: `&e`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(_t) = e { }
+   | |                               --    ^ help: consider borrowing here: `&e`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:40:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
-...
-LL |             Either::One(_t)
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t)
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:47:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
-...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |             Either::One(_t) => (),
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t) => (),
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:56:25
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(mut _t) = x;
-   |               ------    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         let X(mut _t) = x;
+   | |               ------    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:60:38
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^ help: consider borrowing here: `&em`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         if let Either::One(mut _t) = em { }
+   | |                            ------    ^^ help: consider borrowing here: `&em`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:64:41
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^ help: consider borrowing here: `&em`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(mut _t) = em { }
+   | |                               ------    ^^ help: consider borrowing here: `&em`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:68:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t)
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t)
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:75:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
-...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:95:21
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(_t) = x;
-   |               --    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+   | |               --    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL | |
+LL | |
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:99:34
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         if let Either::One(_t) = e { }
-   |                            --    ^ help: consider borrowing here: `&e`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+LL | |
+LL | |         if let Either::One(_t) = e { }
+   | |                            --    ^ help: consider borrowing here: `&e`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:103:37
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         while let Either::One(_t) = e { }
-   |                               --    ^ help: consider borrowing here: `&e`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(_t) = e { }
+   | |                               --    ^ help: consider borrowing here: `&e`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:107:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
-...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |             Either::One(_t)
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t)
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:114:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
-...
-LL |             Either::One(_t) => (),
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t) => (),
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:123:25
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(mut _t) = x;
-   |               ------    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         let X(mut _t) = x;
+   | |               ------    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:127:38
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^ help: consider borrowing here: `&em`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         if let Either::One(mut _t) = em { }
+   | |                            ------    ^^ help: consider borrowing here: `&em`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:131:41
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^ help: consider borrowing here: `&em`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(mut _t) = em { }
+   | |                               ------    ^^ help: consider borrowing here: `&em`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:135:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t)
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t)
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:142:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
-...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:150:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to 21 previous errors
 
index 93048107e59fcfd82d1820ae5622f8c8222decd9..b111df49f6e5396c20e6d7ec2c2c49d09164a844 100644 (file)
@@ -5,7 +5,9 @@ LL | fn foo() -> impl T<O=()> { S }
    |    --- consider calling this function
 ...
 LL |     bar(foo);
-   |         ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
+   |     --- ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `bar`
   --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:14:16
@@ -23,7 +25,9 @@ error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-shou
 LL |     let closure = || S;
    |                   -- consider calling this closure
 LL |     bar(closure);
-   |         ^^^^^^^ the trait `T` is not implemented for `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:23]`
+   |     --- ^^^^^^^ the trait `T` is not implemented for `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:23]`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `bar`
   --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:14:16
index 39bde52c55a59ea038f02be5f0a62723871f2903..71779ecb7299f1f14bd0a2cc609a6dc73127bdc0 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&S: Trait` is not satisfied
   --> $DIR/imm-ref-trait-object-literal.rs:12:7
    |
 LL |   foo(&s);
-   |       ^^ the trait `Trait` is not implemented for `&S`
+   |   --- ^^ the trait `Trait` is not implemented for `&S`
+   |   |
+   |   required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <&'a mut S as Trait>
@@ -20,10 +22,11 @@ error[E0277]: the trait bound `S: Trait` is not satisfied
   --> $DIR/imm-ref-trait-object-literal.rs:13:7
    |
 LL |   foo(s);
-   |       ^
-   |       |
-   |       expected an implementor of trait `Trait`
-   |       help: consider mutably borrowing here: `&mut s`
+   |   --- ^
+   |   |   |
+   |   |   expected an implementor of trait `Trait`
+   |   |   help: consider mutably borrowing here: `&mut s`
+   |   required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/imm-ref-trait-object-literal.rs:7:11
index bb7919ebb7996338108f03caa21f05031f67647d..229c4b824f27578726d12947fb1474e77c0ae3f4 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
   --> $DIR/impl-trait-with-missing-bounds.rs:14:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
 note: required by a bound in `qux`
@@ -19,7 +21,9 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
   --> $DIR/impl-trait-with-missing-bounds.rs:22:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
 note: required by a bound in `qux`
@@ -36,7 +40,9 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
   --> $DIR/impl-trait-with-missing-bounds.rs:30:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
 note: required by a bound in `qux`
@@ -53,7 +59,9 @@ error[E0277]: `<impl Iterator + std::fmt::Debug as Iterator>::Item` doesn't impl
   --> $DIR/impl-trait-with-missing-bounds.rs:37:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator + std::fmt::Debug as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator + std::fmt::Debug as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator + std::fmt::Debug as Iterator>::Item`
 note: required by a bound in `qux`
@@ -70,7 +78,9 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
   --> $DIR/impl-trait-with-missing-bounds.rs:6:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
 note: required by a bound in `qux`
@@ -87,7 +97,9 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
   --> $DIR/impl-trait-with-missing-bounds.rs:45:13
    |
 LL |         qux(constraint);
-   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
 note: required by a bound in `qux`
index b2be09a4c7f5db89ad91e06077ea99cb02b55e99..93251b2c8dbfc62d91d8102b74300dec54412d43 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
   --> $DIR/issue-62843.rs:4:32
    |
 LL |     println!("{:?}", line.find(pattern));
-   |                                ^^^^^^^
-   |                                |
-   |                                expected an implementor of trait `Pattern<'_>`
-   |                                help: consider borrowing here: `&pattern`
+   |                           ---- ^^^^^^^
+   |                           |    |
+   |                           |    expected an implementor of trait `Pattern<'_>`
+   |                           |    help: consider borrowing here: `&pattern`
+   |                           required by a bound introduced by this call
    |
    = note: the trait bound `String: Pattern<'_>` is not satisfied
    = note: required because of the requirements on the impl of `Pattern<'_>` for `String`
index cd1a8c4be8eccd6ee6651e3cf2b08814f6d3bd08..a3ab0b8efb060860d1a4e41672c2cd1d586bf5a2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
   --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:14:20
    |
 LL |     assert_is_send(&bar);
-   |                    ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+   |     -------------- ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
 note: required by a bound in `assert_is_send`
@@ -19,7 +21,9 @@ error[E0277]: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
   --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:24:20
    |
 LL |     assert_is_send(&bar);
-   |                    ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+   |     -------------- ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
 note: required by a bound in `assert_is_send`
index df1eeb7a2b898a816765705bf53acd0ac3af3cc3..c1a7a2e101d62476c8951efb94d3cd1d9201bf71 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied
   --> $DIR/issue-84973-2.rs:11:9
    |
 LL |     foo(a);
-   |         ^
-   |         |
-   |         expected an implementor of trait `Tr`
-   |         help: consider mutably borrowing here: `&mut a`
+   |     --- ^
+   |     |   |
+   |     |   expected an implementor of trait `Tr`
+   |     |   help: consider mutably borrowing here: `&mut a`
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/issue-84973-2.rs:7:11
index db954530b1bebe34acb5cb34ac2de3a2146e5880..6813b07a2ee64069483b5919d7d583d94cc10de1 100644 (file)
@@ -21,7 +21,6 @@ fn main() {
     let ref_cl: &dyn Fn() -> () = &cl;
     f_sized(*ref_cl);
     //~^ ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
-    //~| ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
 
     use std::rc::Rc;
     let rc = Rc::new(0);
index 2ffe2f5a2b688eb006ffec9d3937776e5ac3c435..ae55c96702adaed6e9fd46b0482a968834e5d53c 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/issue-84973-blacklist.rs:15:12
    |
 LL |     f_copy("".to_string());
-   |            ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |     ------ ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f_copy`
   --> $DIR/issue-84973-blacklist.rs:6:14
@@ -14,7 +16,9 @@ error[E0277]: the trait bound `S: Clone` is not satisfied
   --> $DIR/issue-84973-blacklist.rs:16:13
    |
 LL |     f_clone(S);
-   |             ^ the trait `Clone` is not implemented for `S`
+   |     ------- ^ the trait `Clone` is not implemented for `S`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f_clone`
   --> $DIR/issue-84973-blacklist.rs:7:15
@@ -39,7 +43,9 @@ error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilat
   --> $DIR/issue-84973-blacklist.rs:22:13
    |
 LL |     f_sized(*ref_cl);
-   |             ^^^^^^^ doesn't have a size known at compile-time
+   |     ------- ^^^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `dyn Fn()`
 note: required by a bound in `f_sized`
@@ -49,10 +55,12 @@ LL | fn f_sized<T: Sized>(t: T) {}
    |            ^ required by this bound in `f_sized`
 
 error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
-  --> $DIR/issue-84973-blacklist.rs:28:12
+  --> $DIR/issue-84973-blacklist.rs:27:12
    |
 LL |     f_send(rc);
-   |            ^^ `Rc<{integer}>` cannot be sent between threads safely
+   |     ------ ^^ `Rc<{integer}>` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Rc<{integer}>`
 note: required by a bound in `f_send`
@@ -61,16 +69,6 @@ note: required by a bound in `f_send`
 LL | fn f_send<T: Send>(t: T) {}
    |              ^^^^ required by this bound in `f_send`
 
-error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time
-  --> $DIR/issue-84973-blacklist.rs:22:5
-   |
-LL |     f_sized(*ref_cl);
-   |     ^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Fn()`
-   = note: all function arguments must have a statically known size
-   = help: unsized fn params are gated as an unstable feature
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
index bd1cf6ba61460784357a382a85012243caeae8cf..14b32d8515cd78c82029d5559b79dc693cac2cf9 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied
   --> $DIR/issue-84973-negative.rs:10:9
    |
 LL |     bar(a);
-   |         ^ the trait `Tr` is not implemented for `i32`
+   |     --- ^ the trait `Tr` is not implemented for `i32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `bar`
   --> $DIR/issue-84973-negative.rs:5:11
@@ -14,10 +16,11 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied
   --> $DIR/issue-84973-negative.rs:11:9
    |
 LL |     bar(b);
-   |         ^
-   |         |
-   |         expected an implementor of trait `Tr`
-   |         help: consider borrowing here: `&b`
+   |     --- ^
+   |     |   |
+   |     |   expected an implementor of trait `Tr`
+   |     |   help: consider borrowing here: `&b`
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `bar`
   --> $DIR/issue-84973-negative.rs:5:11
index 649517b7d99da6c8cffb3d78e81e8ee8c836df19..169d0cccb43efe05e0c3df6e8f4e75d19489a961 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied
   --> $DIR/issue-84973.rs:6:24
    |
 LL |     let o = Other::new(f);
-   |                        ^
-   |                        |
-   |                        expected an implementor of trait `SomeTrait`
-   |                        help: consider borrowing here: `&f`
+   |             ---------- ^
+   |             |          |
+   |             |          expected an implementor of trait `SomeTrait`
+   |             |          help: consider borrowing here: `&f`
+   |             required by a bound introduced by this call
    |
 note: required by `Other::<'a, G>::new`
   --> $DIR/issue-84973.rs:27:5
index 3b71d5cee93905fef82baa17191aa4a62cdc4c82..e6a2231390076e02c059bd0b26959f54af4c97ab 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satis
   --> $DIR/mut-borrow-needed-by-trait.rs:17:29
    |
 LL |     let fp = BufWriter::new(fp);
-   |                             ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
+   |              -------------- ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
+   |              |
+   |              required by a bound introduced by this call
    |
    = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
 note: required by `BufWriter::<W>::new`
index f332b7213d8bcc6e5b13b6721308bca4383af306..54f19fe9da445bc476004b244b5c1e8950e4f753 100644 (file)
@@ -4,8 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object
 LL | fn bar(x: &dyn Trait) {}
    |            ^^^^^^^^^ `Trait` cannot be made into an object
    |
-   = help: consider moving `baz` to another trait
-   = help: consider moving `bat` to another trait
 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/object-unsafe-trait-references-self.rs:2:22
    |
@@ -15,6 +13,8 @@ LL |     fn baz(&self, _: Self) {}
    |                      ^^^^ ...because method `baz` references the `Self` type in this parameter
 LL |     fn bat(&self) -> Self {}
    |                      ^^^^ ...because method `bat` references the `Self` type in its return type
+   = help: consider moving `baz` to another trait
+   = help: consider moving `bat` to another trait
 
 error[E0038]: the trait `Other` cannot be made into an object
   --> $DIR/object-unsafe-trait-references-self.rs:10:12
index cfbee1518cd69f72b66487f5689b01f1ff9664d4..a0ce7d05b4d48efecc2aa29787f701d344254ba9 100644 (file)
@@ -1,17 +1,22 @@
 error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
   --> $DIR/option-content-move2.rs:9:9
    |
-LL |     let mut var = None;
-   |         ------- captured outer variable
-...
-LL |         move || {
-   |         ^^^^^^^ move out of `var` occurs here
-LL |
-LL |             var = Some(NotCopyable);
-   |             ---
-   |             |
-   |             move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
-   |             move occurs due to use in closure
+LL |       let mut var = None;
+   |           ------- captured outer variable
+LL |       func(|| {
+   |  __________-
+LL | |         // Shouldn't suggest `move ||.as_ref()` here
+LL | |         move || {
+   | |         ^^^^^^^ move out of `var` occurs here
+LL | |
+LL | |             var = Some(NotCopyable);
+   | |             ---
+   | |             |
+   | |             move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+   | |             move occurs due to use in closure
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to previous error
 
index b62502fb6a2b13779aac2675bd19da886ddf73ed..551a7c5060fc743e9b677ab3a67d63e0954e3fa0 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `impl Sync` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:4:13
    |
 LL |     is_send(val);
-   |             ^^^ `impl Sync` cannot be sent between threads safely
+   |     ------- ^^^ `impl Sync` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
@@ -18,7 +20,9 @@ error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:8:13
    |
 LL |     is_send(val);
-   |             ^^^ `S` cannot be sent between threads safely
+   |     ------- ^^^ `S` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
@@ -34,7 +38,9 @@ error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:12:13
    |
 LL |     is_send(val);
-   |             ^^^ `S` cannot be sent between threads safely
+   |     ------- ^^^ `S` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
@@ -50,7 +56,9 @@ error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:20:13
    |
 LL |     is_send(val);
-   |             ^^^ `S` cannot be sent between threads safely
+   |     ------- ^^^ `S` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
@@ -66,7 +74,9 @@ error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:24:13
    |
 LL |     is_send(val);
-   |             ^^^ `S` cannot be sent between threads safely
+   |     ------- ^^^ `S` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
@@ -82,7 +92,9 @@ error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:28:13
    |
 LL |     is_send(val);
-   |             ^^^ `S` cannot be sent between threads safely
+   |     ------- ^^^ `S` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
index 1f14ebae84127220c5e692af00cf2c399a7decc4..8dfab8dfa17e5bc1b50b1ab4df1d84cd1721f5ba 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
   --> $DIR/suggest-change-mut.rs:12:48
    |
 LL |         let mut stream_reader = BufReader::new(&stream);
-   |                                                ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
+   |                                 -------------- ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
+   |                                 |
+   |                                 required by a bound introduced by this call
    |
 note: required by `BufReader::<R>::new`
   --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
diff --git a/src/test/ui/symbol-names/issue-53912.rs b/src/test/ui/symbol-names/issue-53912.rs
new file mode 100644 (file)
index 0000000..65b6825
--- /dev/null
@@ -0,0 +1,37 @@
+// build-pass
+
+// This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
+// reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
+// symbol mangling fix produces the correct result.
+
+fn dummy() {}
+
+mod llvm {
+    pub(crate) struct Foo;
+}
+mod foo {
+    pub(crate) struct Foo<T>(T);
+
+    impl Foo<::llvm::Foo> {
+        pub(crate) fn foo() {
+            for _ in 0..0 {
+                for _ in &[::dummy()] {
+                    ::dummy();
+                    ::dummy();
+                    ::dummy();
+                }
+            }
+        }
+    }
+
+    pub(crate) fn foo() {
+        Foo::foo();
+        Foo::foo();
+    }
+}
+
+pub fn foo() {
+    foo::foo();
+}
+
+fn main() {}
diff --git a/src/test/ui/test-attrs/issue-36768.rs b/src/test/ui/test-attrs/issue-36768.rs
new file mode 100644 (file)
index 0000000..f671cbc
--- /dev/null
@@ -0,0 +1,9 @@
+// run-pass
+// compile-flags:--test
+#![deny(private_in_public)]
+
+#[test] fn foo() {}
+mod foo {}
+
+#[test] fn core() {}
+extern crate core;
diff --git a/src/test/ui/thread-local/tls.rs b/src/test/ui/thread-local/tls.rs
new file mode 100644 (file)
index 0000000..fbd3413
--- /dev/null
@@ -0,0 +1,14 @@
+// run-pass
+// ignore-emscripten no threads support
+// compile-flags: -O
+
+#![feature(thread_local)]
+
+#[thread_local]
+static S: u32 = 222;
+
+fn main() {
+    let local = &S as *const u32 as usize;
+    let foreign = std::thread::spawn(|| &S as *const u32 as usize).join().unwrap();
+    assert_ne!(local, foreign);
+}
diff --git a/src/test/ui/tls.rs b/src/test/ui/tls.rs
deleted file mode 100644 (file)
index fbd3413..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-// ignore-emscripten no threads support
-// compile-flags: -O
-
-#![feature(thread_local)]
-
-#[thread_local]
-static S: u32 = 222;
-
-fn main() {
-    let local = &S as *const u32 as usize;
-    let foreign = std::thread::spawn(|| &S as *const u32 as usize).join().unwrap();
-    assert_ne!(local, foreign);
-}
index 15f5fe16bc7bbcdb0d16ca164222c8fb1e39f2b8..81e5589d6eb3536e2787c4f32f38ff4447acb623 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Foo: main::a::Bar` is not satisfied
   --> $DIR/same-crate-name.rs:31:20
    |
 LL |         a::try_foo(foo);
-   |                    ^^^ the trait `main::a::Bar` is not implemented for `Foo`
+   |         ---------- ^^^ the trait `main::a::Bar` is not implemented for `Foo`
+   |         |
+   |         required by a bound introduced by this call
    |
 help: trait impl with same name found
   --> $DIR/auxiliary/crate_a2.rs:5:1
@@ -20,7 +22,9 @@ error[E0277]: the trait bound `DoesNotImplementTrait: main::a::Bar` is not satis
   --> $DIR/same-crate-name.rs:38:20
    |
 LL |         a::try_foo(implements_no_traits);
-   |                    ^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `DoesNotImplementTrait`
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `DoesNotImplementTrait`
+   |         |
+   |         required by a bound introduced by this call
    |
 note: required by a bound in `try_foo`
   --> $DIR/auxiliary/crate_a1.rs:3:24
@@ -32,7 +36,9 @@ error[E0277]: the trait bound `ImplementsWrongTraitConditionally<isize>: main::a
   --> $DIR/same-crate-name.rs:45:20
    |
 LL |         a::try_foo(other_variant_implements_mismatched_trait);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally<isize>`
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally<isize>`
+   |         |
+   |         required by a bound introduced by this call
    |
 help: trait impl with same name found
   --> $DIR/auxiliary/crate_a2.rs:13:1
@@ -50,7 +56,9 @@ error[E0277]: the trait bound `ImplementsTraitForUsize<isize>: main::a::Bar` is
   --> $DIR/same-crate-name.rs:51:20
    |
 LL |         a::try_foo(other_variant_implements_correct_trait);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize<isize>`
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize<isize>`
+   |         |
+   |         required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <ImplementsTraitForUsize<usize> as main::a::Bar>
diff --git a/src/test/ui/traits/bug-7183-generics.rs b/src/test/ui/traits/bug-7183-generics.rs
new file mode 100644 (file)
index 0000000..f53a173
--- /dev/null
@@ -0,0 +1,36 @@
+// run-pass
+
+trait Speak : Sized {
+    fn say(&self, s:&str) -> String;
+    fn hi(&self) -> String { hello(self) }
+}
+
+fn hello<S:Speak>(s:&S) -> String{
+    s.say("hello")
+}
+
+impl Speak for isize {
+    fn say(&self, s:&str) -> String {
+        format!("{}: {}", s, *self)
+    }
+}
+
+impl<T: Speak> Speak for Option<T> {
+    fn say(&self, s:&str) -> String {
+        match *self {
+            None => format!("{} - none", s),
+            Some(ref x) => { format!("something!{}", x.say(s)) }
+        }
+    }
+}
+
+
+pub fn main() {
+    assert_eq!(3.hi(), "hello: 3".to_string());
+    assert_eq!(Some(Some(3)).hi(),
+               "something!something!hello: 3".to_string());
+    assert_eq!(None::<isize>.hi(), "hello - none".to_string());
+
+    assert_eq!(Some(None::<isize>).hi(), "something!hello - none".to_string());
+    assert_eq!(Some(3).hi(), "something!hello: 3".to_string());
+}
index 5206b5721063a5c1539a59d7942f3617b4e4a63a..7895e50eef5c428e211dd00a54d897f546901ce0 100644 (file)
@@ -10,7 +10,9 @@ error[E0277]: the trait bound `NoClone: Copy` is not satisfied
   --> $DIR/supertrait-auto-trait.rs:16:23
    |
 LL |     let (a, b) = copy(NoClone);
-   |                       ^^^^^^^ the trait `Copy` is not implemented for `NoClone`
+   |                  ---- ^^^^^^^ the trait `Copy` is not implemented for `NoClone`
+   |                  |
+   |                  required by a bound introduced by this call
    |
    = note: required because of the requirements on the impl of `Magic` for `NoClone`
 note: required by a bound in `copy`
diff --git a/src/test/ui/traits/issue-20692.rs b/src/test/ui/traits/issue-20692.rs
new file mode 100644 (file)
index 0000000..1cb2d8c
--- /dev/null
@@ -0,0 +1,11 @@
+trait Array: Sized + Copy {}
+
+fn f<T: Array>(x: &T) {
+    let _ = x
+    //~^ ERROR `Array` cannot be made into an object
+    as
+    &dyn Array;
+    //~^ ERROR `Array` cannot be made into an object
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-20692.stderr b/src/test/ui/traits/issue-20692.stderr
new file mode 100644 (file)
index 0000000..1d7f252
--- /dev/null
@@ -0,0 +1,35 @@
+error[E0038]: the trait `Array` cannot be made into an object
+  --> $DIR/issue-20692.rs:7:5
+   |
+LL |     &dyn Array;
+   |     ^^^^^^^^^^ `Array` 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/issue-20692.rs:1:14
+   |
+LL | trait Array: Sized + Copy {}
+   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
+   |       |      |
+   |       |      ...because it requires `Self: Sized`
+   |       this trait cannot be made into an object...
+
+error[E0038]: the trait `Array` cannot be made into an object
+  --> $DIR/issue-20692.rs:4:13
+   |
+LL |     let _ = x
+   |             ^ `Array` 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/issue-20692.rs:1:14
+   |
+LL | trait Array: Sized + Copy {}
+   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
+   |       |      |
+   |       |      ...because it requires `Self: Sized`
+   |       this trait cannot be made into an object...
+   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T`
+   = note: required by cast to type `&dyn Array`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/issue-23825.rs b/src/test/ui/traits/issue-23825.rs
new file mode 100644 (file)
index 0000000..a9f0095
--- /dev/null
@@ -0,0 +1,21 @@
+// run-pass
+trait Stringify {
+    fn to_string(&self) -> String;
+}
+
+impl Stringify for u32 {
+    fn to_string(&self) -> String { format!("u32: {}", *self) }
+}
+
+impl Stringify for f32 {
+    fn to_string(&self) -> String { format!("f32: {}", *self) }
+}
+
+fn print<T: Stringify>(x: T) -> String {
+    x.to_string()
+}
+
+fn main() {
+    assert_eq!(&print(5), "u32: 5");
+    assert_eq!(&print(5.0), "f32: 5");
+}
index 2260dcfc70ea38f4d4eff58a6ca91234fba9d67a..ef5d5cdff8f4b14f2d4df31bd715af7d70e71444 100644 (file)
@@ -127,9 +127,6 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object
 LL |     <dyn C>::A;
    |      ^^^^^ `assoc_const::C` cannot be made into an object
    |
-   = help: consider moving `C` to another trait
-   = help: consider moving `B` to another trait
-   = help: consider moving `A` to another trait
 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/item-privacy.rs:25:15
    |
@@ -143,6 +140,9 @@ LL |     pub trait C: A + B {
    |               - this trait cannot be made into an object...
 LL |         const C: u8 = 0;
    |               ^ ...because it contains this associated `const`
+   = help: consider moving `C` to another trait
+   = help: consider moving `A` to another trait
+   = help: consider moving `B` to another trait
 
 error[E0223]: ambiguous associated type
   --> $DIR/item-privacy.rs:115:12
index ad95e06eb4e521ae0bee0e586ac5374045a908cb..790e2a81c3a8c0efcdd5ffa6b76b301b866b29b0 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `dummy::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:23:11
    |
 LL |     Outer(TestType);
-   |           ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
+   |     ----- ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `dummy::TestType`
 note: required by `Outer`
@@ -28,7 +30,9 @@ error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:32:13
    |
 LL |     is_send(TestType);
-   |             ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
+   |     ------- ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `dummy1b::TestType`
 note: required by a bound in `is_send`
@@ -41,9 +45,11 @@ error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:40:13
    |
 LL |     is_send((8, TestType));
-   |             ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
+   |     ------- ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
-   = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType`
+   = help: the trait `Send` is not implemented for `dummy1c::TestType`
    = note: required because it appears within the type `({integer}, dummy1c::TestType)`
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
@@ -55,10 +61,11 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:48:13
    |
 LL |     is_send(Box::new(TestType));
-   |             ^^^^^^^^^^^^^^^^^^
-   |             |
-   |             expected an implementor of trait `Send`
-   |             help: consider borrowing here: `&Box::new(TestType)`
+   |     ------- ^^^^^^^^^^^^^^^^^^
+   |     |       |
+   |     |       expected an implementor of trait `Send`
+   |     |       help: consider borrowing here: `&Box::new(TestType)`
+   |     required by a bound introduced by this call
    |
    = note: the trait bound `dummy2::TestType: Send` is not satisfied
    = note: required because of the requirements on the impl of `Send` for `Unique<dummy2::TestType>`
@@ -73,9 +80,11 @@ error[E0277]: `dummy3::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:56:13
    |
 LL |     is_send(Box::new(Outer2(TestType)));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
+   |     ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
-   = help: within `Outer2<dummy3::TestType>`, the trait `Send` is not implemented for `dummy3::TestType`
+   = help: the trait `Send` is not implemented for `dummy3::TestType`
 note: required because it appears within the type `Outer2<dummy3::TestType>`
   --> $DIR/negated-auto-traits-error.rs:12:8
    |
@@ -93,10 +102,11 @@ error[E0277]: `main::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:66:13
    |
 LL |     is_sync(Outer2(TestType));
-   |             ^^^^^^^^^^^^^^^^
-   |             |
-   |             expected an implementor of trait `Sync`
-   |             help: consider borrowing here: `&Outer2(TestType)`
+   |     ------- ^^^^^^^^^^^^^^^^
+   |     |       |
+   |     |       expected an implementor of trait `Sync`
+   |     |       help: consider borrowing here: `&Outer2(TestType)`
+   |     required by a bound introduced by this call
    |
    = note: the trait bound `main::TestType: Sync` is not satisfied
 note: required because of the requirements on the impl of `Sync` for `Outer2<main::TestType>`
index 526c0e9ed540fa3485fbe1d8726246bdc19f87d8..e7d1ee616b34f731f4dfe5bd7e6c54d6d85ffba2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `(): MyTrait` is not satisfied
   --> $DIR/no-use.rs:10:26
    |
 LL |     <() as MyTrait>::foo(&());
-   |                          ^^^ the trait `MyTrait` is not implemented for `()`
+   |     -------------------- ^^^ the trait `MyTrait` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <() as MyTrait>
index 10eeec20d98d761c1a6ee07385fdcfa79b17227d..2c225f4311d017fd5a72f65dec9f0702b7c02dea 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied
   --> $DIR/issue-39029.rs:16:37
    |
 LL |     let _errors = TcpListener::bind(&bad);
-   |                                     ^^^^
-   |                                     |
-   |                                     the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
-   |                                     help: consider adding dereference here: `&*bad`
+   |                   ----------------- ^^^^
+   |                   |                 |
+   |                   |                 the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
+   |                   |                 help: consider adding dereference here: `&*bad`
+   |                   required by a bound introduced by this call
    |
    = note: required because of the requirements on the impl of `ToSocketAddrs` for `&NoToSocketAddrs`
 note: required by a bound in `TcpListener::bind`
index 750c8a86c56ddd5a387defc4380efb63d344f0d0..b77af7ddf474628863341ce536372d48bbed572e 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `&String: SomeTrait` is not satisfied
   --> $DIR/issue-62530.rs:13:26
    |
 LL |     takes_type_parameter(&string);  // Error
-   |                          ^^^^^^^
-   |                          |
-   |                          the trait `SomeTrait` is not implemented for `&String`
-   |                          help: consider adding dereference here: `&*string`
+   |     -------------------- ^^^^^^^
+   |     |                    |
+   |     |                    the trait `SomeTrait` is not implemented for `&String`
+   |     |                    help: consider adding dereference here: `&*string`
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `takes_type_parameter`
   --> $DIR/issue-62530.rs:4:44
index 6fcf8780d6e225c1cac761d4a133bcea5e38d184..bf9f85f1b4595ec4d2c541145af0b83ffd637068 100644 (file)
@@ -2,10 +2,11 @@ error[E0277]: the trait bound `&Baz: Happy` is not satisfied
   --> $DIR/multiple-0.rs:34:9
    |
 LL |     foo(&baz);
-   |         ^^^^
-   |         |
-   |         the trait `Happy` is not implemented for `&Baz`
-   |         help: consider adding dereference here: `&***baz`
+   |     --- ^^^^
+   |     |   |
+   |     |   the trait `Happy` is not implemented for `&Baz`
+   |     |   help: consider adding dereference here: `&***baz`
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/multiple-0.rs:30:26
index 268f375050a4c8c618068e02be60854a2ce6742e..040fbb3e3e699813fae132946c7076eddfcd92d2 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `&mut Baz: Happy` is not satisfied
   --> $DIR/multiple-1.rs:52:9
    |
 LL |     foo(&mut baz);
-   |         ^^^^^^^^ the trait `Happy` is not implemented for `&mut Baz`
+   |     --- ^^^^^^^^ the trait `Happy` is not implemented for `&mut Baz`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
   --> $DIR/multiple-1.rs:45:26
index 0289424510f9781cebb0e0ecc267897e5d9ad9ab..d943b48fd0082115045e051a5f884cf56b545fe3 100644 (file)
@@ -32,8 +32,6 @@ error[E0038]: the trait `bar` cannot be made into an object
 LL |     (box 10 as Box<dyn bar>).dup();
    |                ^^^^^^^^^^^^ `bar` cannot be made into an object
    |
-   = help: consider moving `dup` to another trait
-   = help: consider moving `blah` to another trait
 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
    |
@@ -42,6 +40,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |       |                      |
    |       |                      ...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:6
@@ -49,8 +49,6 @@ error[E0038]: the trait `bar` cannot be made into an object
 LL |     (box 10 as Box<dyn bar>).dup();
    |      ^^^^^^ `bar` cannot be made into an object
    |
-   = help: consider moving `dup` to another trait
-   = help: consider moving `blah` to another trait
 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
    |
@@ -59,6 +57,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |       |                      |
    |       |                      ...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
    = 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>`
 
index 97ef2dd37f7910f2f6ab3ce0155899e0e4fb8563..d9e0d21541edefaa2ac7cd83cdde96bf95bfe68f 100644 (file)
@@ -24,7 +24,9 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:25:15
    |
 LL |     Foo::test(&4i32);
-   |               ^^^^^ the trait `Foo` is not implemented for `i32`
+   |     --------- ^^^^^ the trait `Foo` is not implemented for `i32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by `Foo::test`
   --> $DIR/trivial-bounds-leak.rs:5:5
@@ -36,7 +38,9 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:26:22
    |
 LL |     generic_function(5i32);
-   |                      ^^^^ the trait `Foo` is not implemented for `i32`
+   |     ---------------- ^^^^ the trait `Foo` is not implemented for `i32`
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `generic_function`
   --> $DIR/trivial-bounds-leak.rs:29:24
index 2de5f6eb0f03aa25ed69a9d7971d3248bc1d201a..8a296dc7ee6e12506d7c5f12cd1f4d7507886786 100644 (file)
@@ -16,7 +16,6 @@ error[E0038]: the trait `MyAdd` cannot be made into an object
 LL |     let y = x as dyn MyAdd<i32>;
    |                  ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object
    |
-   = help: consider moving `add` to another trait
 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/type-parameter-defaults-referencing-Self-ppaux.rs:6:55
    |
@@ -24,6 +23,7 @@ LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
    |       -----                                           ^^^^ ...because method `add` references the `Self` type in its return type
    |       |
    |       this trait cannot be made into an object...
+   = help: consider moving `add` to another trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.fixed b/src/test/ui/typeck/issue-88803-call-expr-method.fixed
new file mode 100644 (file)
index 0000000..19b96ec
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+    let a = Some(42);
+    println!(
+        "The value is {}.",
+        a.unwrap() //~ERROR [E0615]
+    );
+}
diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.rs b/src/test/ui/typeck/issue-88803-call-expr-method.rs
new file mode 100644 (file)
index 0000000..a061994
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+    let a = Some(42);
+    println!(
+        "The value is {}.",
+        (a.unwrap)() //~ERROR [E0615]
+    );
+}
diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.stderr b/src/test/ui/typeck/issue-88803-call-expr-method.stderr
new file mode 100644 (file)
index 0000000..dd717ed
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>`
+  --> $DIR/issue-88803-call-expr-method.rs:7:12
+   |
+LL |         (a.unwrap)()
+   |            ^^^^^^ method, not a field
+   |
+help: remove wrapping parentheses to call the method
+   |
+LL -         (a.unwrap)()
+LL +         a.unwrap()
+   | 
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0615`.
diff --git a/src/test/ui/typeck/issue-88844.rs b/src/test/ui/typeck/issue-88844.rs
new file mode 100644 (file)
index 0000000..116c75a
--- /dev/null
@@ -0,0 +1,14 @@
+// Regression test for #88844.
+
+struct Struct { value: i32 }
+//~^ NOTE: similarly named struct `Struct` defined here
+
+impl Stuct {
+//~^ ERROR: cannot find type `Stuct` in this scope [E0412]
+//~| HELP: a struct with a similar name exists
+    fn new() -> Self {
+        Self { value: 42 }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-88844.stderr b/src/test/ui/typeck/issue-88844.stderr
new file mode 100644 (file)
index 0000000..90bba90
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `Stuct` in this scope
+  --> $DIR/issue-88844.rs:6:6
+   |
+LL | struct Struct { value: i32 }
+   | ------------- similarly named struct `Struct` defined here
+...
+LL | impl Stuct {
+   |      ^^^^^ help: a struct with a similar name exists: `Struct`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
index c0f388bd15b28a46d8b9fe635d0aeb61d9a3417a..4b5804253b23b7efa555e35ce0ff0601eab5bc97 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: `UnsafeCell<MySync<{integer}>>` cannot be shared between threads s
   --> $DIR/typeck-unsafe-always-share.rs:19:10
    |
 LL |     test(us);
-   |          ^^ `UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
+   |     ---- ^^ `UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `UnsafeCell<MySync<{integer}>>`
 note: required by a bound in `test`
@@ -15,7 +17,9 @@ error[E0277]: `UnsafeCell<NoSync>` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:23:10
    |
 LL |     test(uns);
-   |          ^^^ `UnsafeCell<NoSync>` cannot be shared between threads safely
+   |     ---- ^^^ `UnsafeCell<NoSync>` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `UnsafeCell<NoSync>`
 note: required by a bound in `test`
@@ -46,7 +50,9 @@ error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:30:10
    |
 LL |     test(NoSync);
-   |          ^^^^^^ `NoSync` cannot be shared between threads safely
+   |     ---- ^^^^^^ `NoSync` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `NoSync`
 note: required by a bound in `test`
index f8c90176ff134dac28211ed7eb80b74985f0600c..482d3e44fe4ea7f0656ff49342c76ddb0e1c8905 100644 (file)
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(|| drop(x));
-   |                               ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       --------^-
+   |                       |       |
+   |                       |       move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:19:35
@@ -12,7 +15,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(|| drop(x));
-   |                                   ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           --------^-
+   |                           |       |
+   |                           |       move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:28:36
@@ -20,7 +26,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(move || drop(x));
-   |                                    ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       -------------^-
+   |                       |            |
+   |                       |            move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:32:40
@@ -28,7 +37,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(move || drop(x));
-   |                                        ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           -------------^-
+   |                           |            |
+   |                           |            move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           captured by this `FnMut` closure
 
 error: aborting due to 4 previous errors
 
index f30bf40983e23cfe74790311632f332682d8568d..c8ce3091cf611f54d71be90a106296a2f9afc3ce 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<(isize,)>` closure, found `S`
   --> $DIR/unboxed-closures-fnmut-as-fn.rs:28:21
    |
 LL |     let x = call_it(&S, 22);
-   |                     ^^ expected an `Fn<(isize,)>` closure, found `S`
+   |             ------- ^^ expected an `Fn<(isize,)>` closure, found `S`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `Fn<(isize,)>` is not implemented for `S`
 note: required by a bound in `call_it`
index 6b21b9246f7afd20dc3e4c8fa02e5a87a53ca379..c9a20232f3508891f71b2e47d4afdcbe80c08783 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r i
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:20:21
    |
 LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it`
@@ -15,7 +17,9 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:25:25
    |
 LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it_mut`
@@ -28,7 +32,9 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:30:26
    |
 LL |     let z = call_it_once(square, 22);
-   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it_once`
index 936cb27759aad7e2a271a0659b05799c1a71d11e..77c176de625ca95e456b7d3af0dd3a7b3e631b7e 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&
   --> $DIR/unboxed-closures-wrong-abi.rs:20:21
    |
 LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it`
@@ -15,7 +17,9 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `for<'r> extern "C" f
   --> $DIR/unboxed-closures-wrong-abi.rs:25:25
    |
 LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it_mut`
@@ -28,7 +32,9 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `for<'r> extern "C"
   --> $DIR/unboxed-closures-wrong-abi.rs:30:26
    |
 LL |     let z = call_it_once(square, 22);
-   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 note: required by a bound in `call_it_once`
index f9f1182e30998a63def1cee27e7209fc384f3f4f..64d57773d70810ccec4703af0df870e999938150 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isi
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:21:21
    |
 LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 note: required by a bound in `call_it`
@@ -15,7 +17,9 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `unsafe fn(isize) ->
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:26:25
    |
 LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 note: required by a bound in `call_it_mut`
@@ -28,7 +32,9 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) ->
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:31:26
    |
 LL |     let z = call_it_once(square, 22);
-   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |             |
+   |             required by a bound introduced by this call
    |
    = help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 note: required by a bound in `call_it_once`
diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.rs b/src/test/ui/unnamed_fields/restrict_anonymous.rs
deleted file mode 100644 (file)
index 99637d1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(unnamed_fields)]
-
-fn f() -> struct { field: u8 } {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-fn f2(a: struct { field: u8 } ) {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-union G {
-    field: struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-}
-//~| ERROR unions may not contain fields that need dropping [E0740]
-
-struct H { _: u8 } // Should error after hir checks
-
-struct I(struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous structs are unimplemented
-
-enum J {
-    K(struct { field: u8 }), //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-    L {
-        _ : struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-        //~^ ERROR anonymous fields are not allowed outside of structs or unions
-        //~| ERROR anonymous structs are unimplemented
-    },
-    M {
-        _ : u8 //~ ERROR anonymous fields are not allowed outside of structs or unions
-    }
-}
-
-static M: union { field: u8 } = 0; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous unions are unimplemented
-
-type N = union { field: u8 }; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
-//~^ ERROR anonymous unions are unimplemented
-
-fn main() {
-    const O: struct { field: u8 } = 0; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-
-    let p: [struct { field: u8 }; 1]; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-
-    let q: (struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-
-    let cl = || -> struct { field: u8 } {}; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
-    //~^ ERROR anonymous structs are unimplemented
-}
diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.stderr b/src/test/ui/unnamed_fields/restrict_anonymous.stderr
deleted file mode 100644 (file)
index efcf544..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:4:11
-   |
-LL | fn f() -> struct { field: u8 } {}
-   |           ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:7:10
-   |
-LL | fn f2(a: struct { field: u8 } ) {}
-   |          ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:11:12
-   |
-LL |     field: struct { field: u8 }
-   |            ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:18:10
-   |
-LL | struct I(struct { field: u8 }, u8);
-   |          ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:22:7
-   |
-LL |     K(struct { field: u8 }),
-   |       ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous fields are not allowed outside of structs or unions
-  --> $DIR/restrict_anonymous.rs:25:9
-   |
-LL |         _ : struct { field: u8 }
-   |         -^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         anonymous field declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:25:13
-   |
-LL |         _ : struct { field: u8 }
-   |             ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous fields are not allowed outside of structs or unions
-  --> $DIR/restrict_anonymous.rs:30:9
-   |
-LL |         _ : u8
-   |         -^^^^^
-   |         |
-   |         anonymous field declared here
-
-error: anonymous unions are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:34:11
-   |
-LL | static M: union { field: u8 } = 0;
-   |           ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
-
-error: anonymous unions are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:37:10
-   |
-LL | type N = union { field: u8 };
-   |          ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:41:14
-   |
-LL |     const O: struct { field: u8 } = 0;
-   |              ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:44:13
-   |
-LL |     let p: [struct { field: u8 }; 1];
-   |             ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:47:13
-   |
-LL |     let q: (struct { field: u8 }, u8);
-   |             ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are not allowed outside of unnamed struct or union fields
-  --> $DIR/restrict_anonymous.rs:50:20
-   |
-LL |     let cl = || -> struct { field: u8 } {};
-   |                    ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:4:11
-   |
-LL | fn f() -> struct { field: u8 } {}
-   |           ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:7:10
-   |
-LL | fn f2(a: struct { field: u8 } ) {}
-   |          ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:11:12
-   |
-LL |     field: struct { field: u8 }
-   |            ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:18:10
-   |
-LL | struct I(struct { field: u8 }, u8);
-   |          ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:22:7
-   |
-LL |     K(struct { field: u8 }),
-   |       ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:25:13
-   |
-LL |         _ : struct { field: u8 }
-   |             ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous unions are unimplemented
-  --> $DIR/restrict_anonymous.rs:34:11
-   |
-LL | static M: union { field: u8 } = 0;
-   |           ^^^^^^^^^^^^^^^^^^^
-
-error: anonymous unions are unimplemented
-  --> $DIR/restrict_anonymous.rs:37:10
-   |
-LL | type N = union { field: u8 };
-   |          ^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:44:13
-   |
-LL |     let p: [struct { field: u8 }; 1];
-   |             ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:47:13
-   |
-LL |     let q: (struct { field: u8 }, u8);
-   |             ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:50:20
-   |
-LL |     let cl = || -> struct { field: u8 } {};
-   |                    ^^^^^^^^^^^^^^^^^^^^
-
-error: anonymous structs are unimplemented
-  --> $DIR/restrict_anonymous.rs:41:14
-   |
-LL |     const O: struct { field: u8 } = 0;
-   |              ^^^^^^^^^^^^^^^^^^^^
-
-error[E0740]: unions may not contain fields that need dropping
-  --> $DIR/restrict_anonymous.rs:11:5
-   |
-LL |     field: struct { field: u8 }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: `std::mem::ManuallyDrop` can be used to wrap the type
-  --> $DIR/restrict_anonymous.rs:11:5
-   |
-LL |     field: struct { field: u8 }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 27 previous errors
-
-For more information about this error, try `rustc --explain E0740`.
diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.mir.stderr
new file mode 100644 (file)
index 0000000..9e9cbcf
--- /dev/null
@@ -0,0 +1,35 @@
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+LL |         let f = |v: &mut Vec<_>| {
+LL |             unsafe {
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8
+   |
+LL | #[deny(unused_unsafe)]
+   |        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |                 |w: &mut Vec<u32>| { unsafe {
+   |                                      ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |             |x: &mut Vec<u32>| { unsafe {
+   |                                  ^^^^^^ unnecessary `unsafe` block
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.rs
new file mode 100644 (file)
index 0000000..ac1cfd6
--- /dev/null
@@ -0,0 +1,28 @@
+// revisions: mir thir
+// [thir]compile-flags: -Zthir-unsafeck
+
+#[deny(unused_unsafe)]
+fn main() {
+    let mut v = Vec::<i32>::with_capacity(24);
+
+    unsafe {
+        let f = |v: &mut Vec<_>| {
+            unsafe { //~ ERROR unnecessary `unsafe`
+                v.set_len(24);
+                |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe`
+                    w.set_len(32);
+                } };
+            }
+            |x: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe`
+                x.set_len(40);
+            } };
+        };
+
+        v.set_len(0);
+        f(&mut v);
+    }
+
+    |y: &mut Vec<u32>| { unsafe {
+        y.set_len(48);
+    } };
+}
diff --git a/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr b/src/test/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.thir.stderr
new file mode 100644 (file)
index 0000000..9e9cbcf
--- /dev/null
@@ -0,0 +1,35 @@
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:10:13
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+LL |         let f = |v: &mut Vec<_>| {
+LL |             unsafe {
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:4:8
+   |
+LL | #[deny(unused_unsafe)]
+   |        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |                 |w: &mut Vec<u32>| { unsafe {
+   |                                      ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:16:34
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |             |x: &mut Vec<u32>| { unsafe {
+   |                                  ^^^^^^ unnecessary `unsafe` block
+
+error: aborting due to 3 previous errors
+
index a7f57e3fd15667d81396d6c40e1293565bde5a18..6686e55130fb453579d774d736238a9282612281 100644 (file)
@@ -12,9 +12,11 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
   --> $DIR/unsized-exprs.rs:24:22
    |
 LL |     udrop::<A<[u8]>>(A { 0: *foo() });
-   |                      ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ---------------- ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
-   = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
+   = help: the trait `Sized` is not implemented for `[u8]`
 note: required because it appears within the type `A<[u8]>`
   --> $DIR/unsized-exprs.rs:3:8
    |
index f5b5d02593155963477ca07a306c15b9bd305550..39b6583bc4ec4123d915ad1372e47022b1c6973e 100644 (file)
@@ -44,8 +44,6 @@ fn f9<X: ?Sized>(x1: Box<S<X>>) {
 fn f10<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(32, *x1));
     //~^ ERROR the size for values of type
-    //~| ERROR the size for values of type
 }
 
-pub fn main() {
-}
+pub fn main() {}
index f7bb6c9c78c65ef4141e3e1b7adeebc3d44ceeff..ae89f2f997728cc2de862b0cca3517d81bdedc03 100644 (file)
@@ -4,7 +4,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
 LL | fn f1<X: ?Sized>(x: &X) {
    |       - this type parameter needs to be `std::marker::Sized`
 LL |     f2::<X>(x);
-   |             ^ doesn't have a size known at compile-time
+   |     ------- ^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f2`
   --> $DIR/unsized3.rs:10:7
@@ -27,7 +29,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
 LL | fn f3<X: ?Sized + T>(x: &X) {
    |       - this type parameter needs to be `std::marker::Sized`
 LL |     f4::<X>(x);
-   |             ^ doesn't have a size known at compile-time
+   |     ------- ^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required by a bound in `f4`
   --> $DIR/unsized3.rs:21:7
@@ -50,7 +54,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
 LL | fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
    |       - this type parameter needs to be `std::marker::Sized`
 LL |     f5(x1);
-   |        ^^ doesn't have a size known at compile-time
+   |     -- ^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because it appears within the type `S<X>`
   --> $DIR/unsized3.rs:28:8
@@ -78,7 +84,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
 LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
    |       - this type parameter needs to be `std::marker::Sized`
 LL |     f5(&(*x1, 34));
-   |        ^^^^^^^^^^ doesn't have a size known at compile-time
+   |     -- ^^^^^^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because it appears within the type `S<X>`
   --> $DIR/unsized3.rs:28:8
@@ -92,34 +100,15 @@ LL - fn f9<X: ?Sized>(x1: Box<S<X>>) {
 LL + fn f9<X>(x1: Box<S<X>>) {
    | 
 
-error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:45:9
-   |
-LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
-   |        - this type parameter needs to be `std::marker::Sized`
-LL |     f5(&(32, *x1));
-   |         ^^^^^^^^^ doesn't have a size known at compile-time
-   |
-note: required because it appears within the type `S<X>`
-  --> $DIR/unsized3.rs:28:8
-   |
-LL | struct S<X: ?Sized> {
-   |        ^
-   = note: required because it appears within the type `({integer}, S<X>)`
-   = note: tuples must have a statically known size to be initialized
-help: consider removing the `?Sized` bound to make the type parameter `Sized`
-   |
-LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
-LL + fn f10<X>(x1: Box<S<X>>) {
-   | 
-
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:45:8
    |
 LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
    |        - this type parameter needs to be `std::marker::Sized`
 LL |     f5(&(32, *x1));
-   |        ^^^^^^^^^^ doesn't have a size known at compile-time
+   |     -- ^^^^^^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
 note: required because it appears within the type `S<X>`
   --> $DIR/unsized3.rs:28:8
@@ -127,21 +116,13 @@ note: required because it appears within the type `S<X>`
 LL | struct S<X: ?Sized> {
    |        ^
    = note: required because it appears within the type `({integer}, S<X>)`
-note: required by a bound in `f5`
-  --> $DIR/unsized3.rs:24:7
-   |
-LL | fn f5<Y>(x: &Y) {}
-   |       ^ required by this bound in `f5`
+   = note: tuples must have a statically known size to be initialized
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
 LL + fn f10<X>(x1: Box<S<X>>) {
    | 
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | fn f5<Y: ?Sized>(x: &Y) {}
-   |        ++++++++
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/use-self-in-inner-fn.rs b/src/test/ui/use-self-in-inner-fn.rs
deleted file mode 100644 (file)
index eccb315..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-struct A;
-
-impl A {
-//~^ NOTE `Self` type implicitly declared here, by this `impl`
-    fn banana(&mut self) {
-        fn peach(this: &Self) {
-        //~^ ERROR can't use generic parameters from outer function
-        //~| NOTE use of generic parameter from outer function
-        //~| NOTE use a type here instead
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/use-self-in-inner-fn.stderr b/src/test/ui/use-self-in-inner-fn.stderr
deleted file mode 100644 (file)
index 9660934..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0401]: can't use generic parameters from outer function
-  --> $DIR/use-self-in-inner-fn.rs:6:25
-   |
-LL | impl A {
-   | ---- `Self` type implicitly declared here, by this `impl`
-...
-LL |         fn peach(this: &Self) {
-   |                         ^^^^
-   |                         |
-   |                         use of generic parameter from outer function
-   |                         use a type here instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0401`.
index bff64813268ce687c4011d776077aed30a0e1878..c5fff622b6b232941913ef93fe33ee2fa67a3fd1 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `{integer}: TraitA` is not satisfied
   --> $DIR/vtable-res-trait-param.rs:17:18
    |
 LL |     b.gimme_an_a(y)
-   |                  ^ the trait `TraitA` is not implemented for `{integer}`
+   |       ---------- ^ the trait `TraitA` is not implemented for `{integer}`
+   |       |
+   |       required by a bound introduced by this call
 
 error: aborting due to previous error
 
index 010200b5ded1f40faf3355bf3b6e09b834c152f9..c924cd87997e137a864a6e5cc73d37b983e1743b 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `T` cannot be made into an object
 LL |     const CONST: (bool, dyn T);
    |                         ^^^^^ `T` cannot be made into an object
    |
-   = help: consider moving `CONST` to another trait
 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/issue-87495.rs:4:11
    |
@@ -12,6 +11,7 @@ LL | trait T {
    |       - this trait cannot be made into an object...
 LL |     const CONST: (bool, dyn T);
    |           ^^^^^ ...because it contains this associated `const`
+   = help: consider moving `CONST` to another trait
 
 error: aborting due to previous error
 
index 9b749f88fb810e173271052f63cddd6118da9771..64969fbe3203e0af8fdbccb7c85968c92f9e7a97 100644 (file)
@@ -4,7 +4,6 @@ error[E0038]: the trait `A` cannot be made into an object
 LL |     let _x: &dyn A;
    |             ^^^^^^ `A` cannot be made into an object
    |
-   = help: consider moving `foo` to another trait
 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/wf-object-safe.rs:5:23
    |
@@ -12,6 +11,7 @@ LL | trait A {
    |       - this trait cannot be made into an object...
 LL |     fn foo(&self, _x: &Self);
    |                       ^^^^^ ...because method `foo` references the `Self` type in this parameter
+   = help: consider moving `foo` to another trait
 
 error: aborting due to previous error
 
index 0df5f91c8f3f1e0b157e7c32950658044b35c542..43fbc0a9061cff74b220d25f6a5dd3f65440acc7 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:13:22
    |
 LL |         require_copy(self.x);
-   |                      ^^^^^^ the trait `Copy` is not implemented for `T`
+   |         ------------ ^^^^^^ the trait `Copy` is not implemented for `T`
+   |         |
+   |         required by a bound introduced by this call
    |
 note: required by a bound in `require_copy`
   --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:1:20
index 97d651e0bec9fa9e8e5254f321989fe2f7f1bd3d..f2db8fcc4a3f5e13f1ce9616ef73492e55ab790c 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:18:22
    |
 LL |         require_copy(self.x);
-   |                      ^^^^^^ the trait `Copy` is not implemented for `T`
+   |         ------------ ^^^^^^ the trait `Copy` is not implemented for `T`
+   |         |
+   |         required by a bound introduced by this call
    |
 note: required by a bound in `require_copy`
   --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:1:20
index d7de83104c1dee2ce60f22dba35f149a56e4829c..3223dca3cddbfdb86e2c255e98c2068fd1fe8477 100644 (file)
@@ -2,7 +2,9 @@ error[E0277]: the trait bound `Bar: Eq` is not satisfied
   --> $DIR/where-clauses-method-unsatisfied.rs:18:14
    |
 LL |     x.equals(&x);
-   |              ^^ the trait `Eq` is not implemented for `Bar`
+   |       ------ ^^ the trait `Eq` is not implemented for `Bar`
+   |       |
+   |       required by a bound introduced by this call
 
 error: aborting due to previous error
 
index e515c3277bf0681bfc79a9e763861bfe26bb05db..33ee5f82edb50af87b952c5b28de0f5fb41ebf18 160000 (submodule)
@@ -1 +1 @@
-Subproject commit e515c3277bf0681bfc79a9e763861bfe26bb05db
+Subproject commit 33ee5f82edb50af87b952c5b28de0f5fb41ebf18
index d7e46c2d3eb9d2826966f19fc3d8f98b058a150d..80be4350c3c1a5027bba117e3d78ad09e4d4f9c5 100644 (file)
 pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
 pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
 pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
-pub const PERMISSIONS_FROM_MODE: [&str; 7] = ["std", "os", "imp", "unix", "fs", "PermissionsExt", "from_mode"];
+pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
 pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
 pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
 pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
index f97914b1e97561f40e4a70dc18be66b29da1dff9..04a1d257bc094e317e036da965987159ee5be842 100755 (executable)
@@ -299,7 +299,13 @@ try:
     if repo:
         github_token = os.environ.get('TOOLSTATE_REPO_ACCESS_TOKEN')
         if github_token:
-            validate_maintainers(repo, github_token)
+            # FIXME: This is currently broken. Starting on 2021-09-15, GitHub
+            # seems to have changed it so that to list the collaborators
+            # requires admin permissions. I think this will probably just need
+            # to be removed since we are probably not going to use an admin
+            # token, and I don't see another way to do this.
+            print('maintainer validation disabled')
+            # validate_maintainers(repo, github_token)
         else:
             print('skipping toolstate maintainers validation since no GitHub token is present')
         # When validating maintainers don't run the full script.
index 2483d0570d9eaf1c27358646918b8bd56c50bfcb..14041539b9dfd618536dc240416b65a60f283d3d 100644 (file)
@@ -6,7 +6,7 @@
 use regex::Regex;
 use rustc_ast::visit;
 use rustc_ast::{ast, ptr};
-use rustc_span::{symbol, BytePos, Span};
+use rustc_span::{symbol, BytePos, Span, DUMMY_SP};
 
 use crate::attr::filter_inline_attrs;
 use crate::comment::{
 use crate::utils::*;
 use crate::vertical::rewrite_with_alignment;
 use crate::visitor::FmtVisitor;
-use crate::DEFAULT_VISIBILITY;
+
+const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
+    kind: ast::VisibilityKind::Inherited,
+    span: DUMMY_SP,
+    tokens: None,
+};
 
 fn type_annotation_separator(config: &Config) -> &str {
     colon_spaces(config)
@@ -972,7 +977,7 @@ fn format_header(&self, context: &RewriteContext<'_>, offset: Indent) -> String
         format_header(context, self.prefix, self.ident, self.vis, offset)
     }
 
-    pub(crate) fn from_variant(variant: &'a ast::Variant) -> Self {
+    fn from_variant(variant: &'a ast::Variant) -> Self {
         StructParts {
             prefix: "",
             ident: variant.ident,
index 206d2f782909c9f0639398ce75044b7509ffdc49..47a7b9d4dbe3cb80baa2d08d979e9e94e2b56241 100644 (file)
@@ -32,7 +32,7 @@
 use std::rc::Rc;
 
 use rustc_ast::ast;
-use rustc_span::{symbol, DUMMY_SP};
+use rustc_span::symbol;
 use thiserror::Error;
 
 use crate::comment::LineClasses;
 mod vertical;
 pub(crate) mod visitor;
 
-const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
-    kind: ast::VisibilityKind::Inherited,
-    span: DUMMY_SP,
-    tokens: None,
-};
 /// The various errors that can occur during formatting. Note that not all of
 /// these can currently be propagated to clients.
 #[derive(Error, Debug)]
index 640d127e8609818052a0024ad2aa8f604b215066..76bf58e875b1f6d48218fce5a909ac010ddd2b40 100644 (file)
@@ -1,15 +1,15 @@
 use std::iter::ExactSizeIterator;
 use std::ops::Deref;
 
-use rustc_ast::ast::{self, AttrVec, FnRetTy, Mutability};
-use rustc_span::{symbol::kw, symbol::Ident, BytePos, Pos, Span};
+use rustc_ast::ast::{self, FnRetTy, Mutability};
+use rustc_span::{symbol::kw, BytePos, Pos, Span};
 
+use crate::comment::{combine_strs_with_missing_comments, contains_comment};
 use crate::config::lists::*;
 use crate::config::{IndentStyle, TypeDensity, Version};
 use crate::expr::{
     format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType,
 };
-use crate::items::StructParts;
 use crate::lists::{
     definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
 };
     colon_spaces, extra_offset, first_line_width, format_extern, format_mutability,
     last_line_extendable, last_line_width, mk_sp, rewrite_ident,
 };
-use crate::DEFAULT_VISIBILITY;
-use crate::{
-    comment::{combine_strs_with_missing_comments, contains_comment},
-    items::format_struct_struct,
-};
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub(crate) enum PathContext {
@@ -769,54 +764,6 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
             ast::TyKind::Tup(ref items) => {
                 rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
             }
-            ast::TyKind::AnonymousStruct(ref fields, recovered) => {
-                let ident = Ident::new(
-                    kw::Struct,
-                    mk_sp(self.span.lo(), self.span.lo() + BytePos(6)),
-                );
-                let data = ast::VariantData::Struct(fields.clone(), recovered);
-                let variant = ast::Variant {
-                    attrs: AttrVec::new(),
-                    id: self.id,
-                    span: self.span,
-                    vis: DEFAULT_VISIBILITY,
-                    ident,
-                    data,
-                    disr_expr: None,
-                    is_placeholder: false,
-                };
-                format_struct_struct(
-                    &context,
-                    &StructParts::from_variant(&variant),
-                    fields,
-                    shape.indent,
-                    None,
-                )
-            }
-            ast::TyKind::AnonymousUnion(ref fields, recovered) => {
-                let ident = Ident::new(
-                    kw::Union,
-                    mk_sp(self.span.lo(), self.span.lo() + BytePos(5)),
-                );
-                let data = ast::VariantData::Struct(fields.clone(), recovered);
-                let variant = ast::Variant {
-                    attrs: AttrVec::new(),
-                    id: self.id,
-                    span: self.span,
-                    vis: DEFAULT_VISIBILITY,
-                    ident,
-                    data,
-                    disr_expr: None,
-                    is_placeholder: false,
-                };
-                format_struct_struct(
-                    &context,
-                    &StructParts::from_variant(&variant),
-                    fields,
-                    shape.indent,
-                    None,
-                )
-            }
             ast::TyKind::Path(ref q_self, ref path) => {
                 rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
             }
index 46b5b877b4c26f93b30e56e12b9c949b847c09ee..a341527c84cf065d3b6774cc63b3b21a8a7acf8f 100644 (file)
@@ -7,8 +7,8 @@
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 1345;
-const ISSUES_ENTRY_LIMIT: usize = 2525;
+const ROOT_ENTRY_LIMIT: usize = 1330;
+const ISSUES_ENTRY_LIMIT: usize = 2488;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     let dirs = walkdir::WalkDir::new(&path.join("test/ui"))